


#target photoshop
function showBleedDialog() {
if (app.documents.length === 0) {
alert("សូមបើក Document នៅក្នុង Photoshop ជាមុនសិន!");
return;
}
var doc = app.activeDocument;
// --- UI Window ---
var dlg = new Window('dialog', 'កំណត់ Bleed 1cm + ជ្រើសរើសព័ត៌មាន Label');
dlg.orientation = 'column';
dlg.alignChildren = ['fill', 'top'];
dlg.spacing = 10;
dlg.margins = 15;
// KHMER FONT SETTING (កំណត់ Font និង ទំហំ ១៣pt-១៤pt ឱ្យច្បាស់)
var uiFont = ScriptUI.newFont("Segoe UI", "Regular", 13);
var uiFontBold = ScriptUI.newFont("Segoe UI", "Bold", 13);
// Helper Function សម្រាប់ដាក់ Font ឱ្យគ្រប់ Control
function applyUIFont(container) {
for (var i = 0; i < container.children.length; i++) {
var child = container.children[i];
try {
child.graphics.font = uiFont;
} catch (e) {}
if (child.type === 'panel' || child.type === 'group') {
applyUIFont(child);
}
}
}
// 1. Font Size
var pnlFont = dlg.add('panel', undefined, '១. ទំហំ Font ស្លាកសញ្ញា (pt)');
pnlFont.alignChildren = 'left';
pnlFont.margins = 12;
var txtFontSize = pnlFont.add('edittext', undefined, '18');
txtFontSize.preferredSize = [120, 28];
// 2. Text Color
var pnlColor = dlg.add('panel', undefined, '២. ពណ៌អក្សរ (Color)');
pnlColor.alignChildren = 'left';
pnlColor.margins = 12;
var radBlack = pnlColor.add('radiobutton', undefined, 'ពណ៌ខ្មៅ (Black)');
var radWhite = pnlColor.add('radiobutton', undefined, 'ពណ៌ស (White)');
var radRed = pnlColor.add('radiobutton', undefined, 'ពណ៌ក្រហម (Red)');
radBlack.value = true;
// 3. Left Position Options
var pnlPos = dlg.add('panel', undefined, '៣. ទីតាំងអក្សរនៅខាងឆ្វេង');
pnlPos.alignChildren = 'left';
pnlPos.margins = 12;
var radBoth = pnlPos.add('radiobutton', undefined, 'ទាំងលើ ទាំងក្រោម (Top & Bottom)');
var radTop = pnlPos.add('radiobutton', undefined, 'លើខាងឆ្វេង (Top-Left)');
var radBottom = pnlPos.add('radiobutton', undefined, 'ក្រោមខាងឆ្វេង (Bottom-Left)');
var radCenter = pnlPos.add('radiobutton', undefined, 'ចំកណ្ដាល (Center-Left)');
radBoth.value = true;
// 4. Options ទាំង ៥
var pnlOpts = dlg.add('panel', undefined, '៤. ជ្រើសរើសព័ត៌មានបង្ហាញលើ Label');
pnlOpts.alignChildren = 'left';
pnlOpts.margins = 12;
var chkSize = pnlOpts.add('checkbox', undefined, '១. យកខ្នាតរបស់ហ្វាល (cm)');
var chkDpi = pnlOpts.add('checkbox', undefined, '២. យក Resolution (DPI)');
var chkFileName = pnlOpts.add('checkbox', undefined, '៣. យកឈ្មោះដើមរបស់ហ្វាល');
var chkDate = pnlOpts.add('checkbox', undefined, '៤. យកថ្ងៃខែឆ្នាំ (06-Aug-2026)');
chkSize.value = true;
chkDpi.value = true;
chkFileName.value = true;
chkDate.value = true;
// Option 5: សរសេរឈ្មោះហ្វាលថ្មី
var grpCustom = pnlOpts.add('group');
grpCustom.orientation = 'row';
var chkCustom = grpCustom.add('checkbox', undefined, '៥. សរសេរឈ្មោះហ្វាលថ្មី:');
var txtCustom = grpCustom.add('edittext', undefined, '');
txtCustom.preferredSize = [180, 28];
txtCustom.enabled = false;
chkCustom.onClick = function() {
txtCustom.enabled = chkCustom.value;
};
// Buttons
var btnGroup = dlg.add('group');
btnGroup.alignment = 'center';
btnGroup.spacing = 15;
var btnOk = btnGroup.add('button', undefined, 'យល់ព្រម (OK)', {name: 'ok'});
var btnCancel = btnGroup.add('button', undefined, 'បោះបង់ (Cancel)', {name: 'cancel'});
btnOk.preferredSize = [110, 32];
btnCancel.preferredSize = [110, 32];
// អនុវត្ត Font ច្បាស់ៗទៅលើ UI ទាំងមូល
applyUIFont(dlg);
if (dlg.show() !== 1) return;
var fontSizeVal = parseFloat(txtFontSize.text) || 18;
var fontColor = new SolidColor();
if (radWhite.value) {
fontColor.rgb.red = 255; fontColor.rgb.green = 255; fontColor.rgb.blue = 255;
} else if (radRed.value) {
fontColor.rgb.red = 255; fontColor.rgb.green = 0; fontColor.rgb.blue = 0;
} else {
fontColor.rgb.red = 0; fontColor.rgb.green = 0; fontColor.rgb.blue = 0;
}
var posOption = "BOTH";
if (radTop.value) posOption = "TOP";
if (radBottom.value) posOption = "BOTTOM";
if (radCenter.value) posOption = "CENTER";
var cfg = {
fontSize: fontSizeVal,
textColor: fontColor,
posOption: posOption,
incSize: chkSize.value,
incDpi: chkDpi.value,
incFileName: chkFileName.value,
incDate: chkDate.value,
incCustom: chkCustom.value,
customText: txtCustom.text
};
processLeftBleed(doc, cfg);
}
function processLeftBleed(doc, cfg) {
var origRuler = app.preferences.rulerUnits;
var origType = app.preferences.typeUnits;
app.preferences.rulerUnits = Units.CM;
app.preferences.typeUnits = TypeUnits.POINTS;
try {
var origW = doc.width.value;
var origH = doc.height.value;
var imgDpi = Math.round(doc.resolution);
var whiteColor = new SolidColor();
whiteColor.rgb.red = 255; whiteColor.rgb.green = 255; whiteColor.rgb.blue = 255;
app.backgroundColor = whiteColor;
// 1. Expand Canvas 1cm Left
var newW = origW + 1;
doc.resizeCanvas(new UnitValue(newW, "cm"), new UnitValue(origH, "cm"), AnchorPosition.MIDDLERIGHT);
// 2. Add White Background Layer
var bgLayer = doc.artLayers.add();
bgLayer.name = "Bleed Background (Left)";
var bottomLayer = doc.layers[doc.layers.length - 1];
if (bottomLayer !== bgLayer) {
bgLayer.move(bottomLayer, ElementPlacement.PLACEBEFORE);
}
// Fill 1cm Left Area
var selectionArea = [
[new UnitValue(0, "cm"), new UnitValue(0, "cm")],
[new UnitValue(1, "cm"), new UnitValue(0, "cm")],
[new UnitValue(1, "cm"), new UnitValue(origH, "cm")],
[new UnitValue(0, "cm"), new UnitValue(origH, "cm")]
];
doc.selection.select(selectionArea);
doc.selection.fill(whiteColor);
doc.selection.deselect();
// 3. Build Label String
var textParts = [];
if (cfg.incSize) {
var wClean = Math.round(origW * 100) / 100;
var hClean = Math.round(origH * 100) / 100;
textParts.push(wClean + " x " + hClean + " cm");
}
if (cfg.incDpi) {
textParts.push(imgDpi + "dpi");
}
if (cfg.incFileName) {
var docName = doc.name.replace(/\.[^\.~]+$/, "");
textParts.push(docName);
}
if (cfg.incCustom && cfg.customText !== "") {
textParts.push(cfg.customText);
}
if (cfg.incDate) {
var today = new Date();
var dd = String(today.getDate());
if (dd.length < 2) dd = '0' + dd;
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var mmm = months[today.getMonth()];
var yyyy = today.getFullYear();
textParts.push(dd + "-" + mmm + "-" + yyyy);
}
var fullText = textParts.join(" - ");
if (fullText === "") fullText = "Bleed 1cm";
// 4. Create and Align Text Layer
function createAndAlignText(layerName, alignType) {
var textLayer = doc.artLayers.add();
textLayer.kind = LayerKind.TEXT;
textLayer.name = layerName;
var textItem = textLayer.textItem;
textItem.contents = fullText;
textItem.size = cfg.fontSize;
textItem.color = cfg.textColor;
textItem.justification = Justification.CENTER;
textItem.position = [new UnitValue(0.5, "cm"), new UnitValue(origH / 2, "cm")];
textLayer.rotate(-90, AnchorPosition.MIDDLECENTER);
var b = textLayer.bounds;
var curX = (b[0].value + b[2].value) / 2;
var targetCenterX = 0.5;
var deltaX = targetCenterX - curX;
var deltaY = 0;
var margin = 1.5;
if (alignType === "TOP") {
var curTop = b[1].value;
deltaY = margin - curTop;
} else if (alignType === "BOTTOM") {
var curBottom = b[3].value;
deltaY = (origH - margin) - curBottom;
} else if (alignType === "CENTER") {
var curCenterY = (b[1].value + b[3].value) / 2;
deltaY = (origH / 2) - curCenterY;
}
textLayer.translate(new UnitValue(deltaX, "cm"), new UnitValue(deltaY, "cm"));
}
if (cfg.posOption === "TOP") {
createAndAlignText("Bleed Info (Top-Left)", "TOP");
} else if (cfg.posOption === "BOTTOM") {
createAndAlignText("Bleed Info (Bottom-Left)", "BOTTOM");
} else if (cfg.posOption === "CENTER") {
createAndAlignText("Bleed Info (Center)", "CENTER");
} else if (cfg.posOption === "BOTH") {
createAndAlignText("Bleed Info (Top-Left)", "TOP");
createAndAlignText("Bleed Info (Bottom-Left)", "BOTTOM");
}
} catch (err) {
alert("Error: " + err.message);
} finally {
app.preferences.rulerUnits = origRuler;
app.preferences.typeUnits = origType;
}
}
showBleedDialog();