mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
6299c0f8f9
commit
de229c163b
4 files changed
+47
-13
No files matched your search
+23
-3
@@ -3806,9 +3806,16 @@ audio.page-media {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 901px) and (max-width: 1600px) and (pointer: fine) {
|
@media (min-width: 901px) {
|
||||||
.editor-toolbar {
|
.editor-toolbar {
|
||||||
--editor-control-width: 52px;
|
flex-wrap: wrap;
|
||||||
|
row-gap: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 901px) and (max-width: 1600px) {
|
||||||
|
.editor-toolbar {
|
||||||
|
--editor-control-width: 44px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-group {
|
.editor-group {
|
||||||
@@ -3820,12 +3827,25 @@ audio.page-media {
|
|||||||
padding-inline: 6px;
|
padding-inline: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-group > select {
|
||||||
|
appearance: none;
|
||||||
|
padding-inline: 2px 10px;
|
||||||
|
background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
|
||||||
|
background-position: right 5px center, right 2px center;
|
||||||
|
background-size: 3px 3px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
.editor-group:has(#textFont) {
|
.editor-group:has(#textFont) {
|
||||||
grid-template-columns: repeat(7, 44px);
|
grid-template-columns: repeat(7, 44px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-paragraph {
|
.editor-paragraph {
|
||||||
grid-template-columns: var(--editor-control-width) 108px;
|
grid-template-columns: var(--editor-control-width) 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-group:has(#shapeFill) {
|
||||||
|
grid-template-columns: repeat(2, 76px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
|||||||
@@ -689,11 +689,12 @@ export class CanvasEditor {
|
|||||||
if (item.contour) item.contour.svg.setAttribute("viewBox", `${item.x} ${item.y} ${item.width} ${item.height}`);
|
if (item.contour) item.contour.svg.setAttribute("viewBox", `${item.x} ${item.y} ${item.width} ${item.height}`);
|
||||||
if (item.textFrame) {
|
if (item.textFrame) {
|
||||||
const { matrix: [a, b, c, d, e, f], width, height } = item.textFrame;
|
const { matrix: [a, b, c, d, e, f], width, height } = item.textFrame;
|
||||||
|
const box = item.textFrame.content || { x: 0, y: 0, width, height };
|
||||||
for (const handle of item.node.children) {
|
for (const handle of item.node.children) {
|
||||||
if (handle.dataset.corner !== "w" && handle.dataset.corner !== "e") continue;
|
if (handle.dataset.corner !== "w" && handle.dataset.corner !== "e") continue;
|
||||||
const x = handle.dataset.corner === "e" ? width : 0;
|
const x = box.x + (handle.dataset.corner === "e" ? box.width : 0), y = box.y + box.height / 2;
|
||||||
handle.style.left = `${(a * x + c * height / 2 + e - item.x) * change.scale * PX_PER_MM}px`;
|
handle.style.left = `${(a * x + c * y + e - item.x) * change.scale * PX_PER_MM}px`;
|
||||||
handle.style.top = `${(b * x + d * height / 2 + f - item.y) * change.scale * PX_PER_MM}px`;
|
handle.style.top = `${(b * x + d * y + f - item.y) * change.scale * PX_PER_MM}px`;
|
||||||
handle.style.cursor = a === 0 ? "var(--resize-vertical, ns-resize)" : "var(--resize-horizontal, ew-resize)";
|
handle.style.cursor = a === 0 ? "var(--resize-vertical, ns-resize)" : "var(--resize-horizontal, ew-resize)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -969,7 +970,7 @@ export class CanvasEditor {
|
|||||||
if (drag.item.textFrame) {
|
if (drag.item.textFrame) {
|
||||||
const frame = drag.item.textFrame, [a, b, c, d] = frame.matrix;
|
const frame = drag.item.textFrame, [a, b, c, d] = frame.matrix;
|
||||||
const dx = (d * (to.x - from.x) - c * (to.y - from.y)) / (a * d - b * c);
|
const dx = (d * (to.x - from.x) - c * (to.y - from.y)) / (a * d - b * c);
|
||||||
const box = reshapeBox({ geometry: { x: 0, y: 0, width: frame.width, height: frame.height } }, dx, 0, drag.corner, false);
|
const box = reshapeBox({ geometry: frame.content || { x: 0, y: 0, width: frame.width, height: frame.height } }, dx, 0, drag.corner, false);
|
||||||
drag.box = { x: drag.item.x + box.x, width: box.width };
|
drag.box = { x: drag.item.x + box.x, width: box.width };
|
||||||
const bounds = transformedBox(box, frame.matrix);
|
const bounds = transformedBox(box, frame.matrix);
|
||||||
Object.assign(drag.item.node.style, { left: `${bounds.x * PX_PER_MM}px`, top: `${bounds.y * PX_PER_MM}px`,
|
Object.assign(drag.item.node.style, { left: `${bounds.x * PX_PER_MM}px`, top: `${bounds.y * PX_PER_MM}px`,
|
||||||
@@ -1130,7 +1131,8 @@ export class CanvasEditor {
|
|||||||
if (drag.corner && drag.box) {
|
if (drag.corner && drag.box) {
|
||||||
this.drag = null;
|
this.drag = null;
|
||||||
this.viewer.releasePointerCapture(drag.pointerID);
|
this.viewer.releasePointerCapture(drag.pointerID);
|
||||||
const geometry = drag.item.oriented?.box || drag.item.geometry || (drag.item.textFrame ? { x: drag.item.x, width: drag.item.textFrame.width } : drag.item);
|
const frame = drag.item.textFrame;
|
||||||
|
const geometry = drag.item.oriented?.box || drag.item.geometry || (frame ? { x: drag.item.x + (frame.content?.x || 0), width: frame.content?.width ?? frame.width } : drag.item);
|
||||||
const changed = Object.keys(drag.box).some((key) => drag.box[key] !== geometry[key]);
|
const changed = Object.keys(drag.box).some((key) => drag.box[key] !== geometry[key]);
|
||||||
const apply = drag.item.shape || drag.item.oriented ? this.options.onReshape : canEditObject(drag.item, "stretch") ? this.options.onResize : this.options.onTextWidth;
|
const apply = drag.item.shape || drag.item.oriented ? this.options.onReshape : canEditObject(drag.item, "stretch") ? this.options.onResize : this.options.onTextWidth;
|
||||||
Promise.resolve(changed && apply(drag.item, drag.box)).finally(() => {
|
Promise.resolve(changed && apply(drag.item, drag.box)).finally(() => {
|
||||||
|
|||||||
@@ -2774,7 +2774,11 @@ func editorRichText(page int, item map[string]any, object ofdgo.GraphicObject, v
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
width, height := local.W, local.H
|
width, height := local.W, local.H
|
||||||
frame := matrix.TransformBox(local)
|
_, contentBounds, err := currentEditor.LayoutRichText(value, width)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
frame := matrix.TransformBox(contentBounds)
|
||||||
format, layout := value.Runs[0].Format, value.Layout
|
format, layout := value.Runs[0].Format, value.Layout
|
||||||
var content strings.Builder
|
var content strings.Builder
|
||||||
for _, run := range value.Runs {
|
for _, run := range value.Runs {
|
||||||
@@ -2792,7 +2796,7 @@ func editorRichText(page int, item map[string]any, object ofdgo.GraphicObject, v
|
|||||||
item["letterSpacing"], item["leftIndent"], item["rightIndent"], item["firstLineIndent"] = layout.LetterSpacing, layout.LeftIndent, layout.RightIndent, layout.FirstLineIndent
|
item["letterSpacing"], item["leftIndent"], item["rightIndent"], item["firstLineIndent"] = layout.LetterSpacing, layout.LeftIndent, layout.RightIndent, layout.FirstLineIndent
|
||||||
item["paragraphWidth"], item["bounds"] = width, editorBox(frame)
|
item["paragraphWidth"], item["bounds"] = width, editorBox(frame)
|
||||||
item["x"], item["y"], item["width"], item["height"] = frame.X, frame.Y, frame.W, frame.H
|
item["x"], item["y"], item["width"], item["height"] = frame.X, frame.Y, frame.W, frame.H
|
||||||
item["textFrame"] = map[string]any{"width": width, "height": height, "matrix": editorMatrix(matrix)}
|
item["textFrame"] = map[string]any{"width": width, "height": height, "matrix": editorMatrix(matrix), "content": editorBox(contentBounds)}
|
||||||
capabilities := item["capabilities"].(map[string]any)
|
capabilities := item["capabilities"].(map[string]any)
|
||||||
for _, key := range []string{"textContent", "rewriteText", "replaceFont", "reflow", "layoutKnown", "paint"} {
|
for _, key := range []string{"textContent", "rewriteText", "replaceFont", "reflow", "layoutKnown", "paint"} {
|
||||||
capabilities[key] = true
|
capabilities[key] = true
|
||||||
|
|||||||
+11
-3
@@ -61,7 +61,7 @@ type richContextShaper struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LayoutRichText 生成局部坐标的标准文字和路径,不修改页面或编辑历史。
|
// LayoutRichText 生成局部坐标的标准文字和路径,不修改页面或编辑历史。
|
||||||
// 边界包含排版高度和溢出墨迹,可能有负的X或Y,不截断文字。
|
// 边界包含内容的排版高度和溢出墨迹,不包含空余段落宽度,可能有负的X或Y。
|
||||||
// 非标准RGB文档按需复用或注册RGB颜色空间,返回对象可直接用于当前文档。
|
// 非标准RGB文档按需复用或注册RGB颜色空间,返回对象可直接用于当前文档。
|
||||||
// 注册不产生修订或撤销记录;失败时不保留新增资源和资源编号。
|
// 注册不产生修订或撤销记录;失败时不保留新增资源和资源编号。
|
||||||
// 提交对象后应创建新的Reader;已有Reader是独立快照,不包含新注册的资源。
|
// 提交对象后应创建新的Reader;已有Reader是独立快照,不包含新注册的资源。
|
||||||
@@ -100,7 +100,7 @@ func (e *Editor) layoutRichText(value RichText, width float64) (richLayout, erro
|
|||||||
return richLayout{}, err
|
return richLayout{}, err
|
||||||
}
|
}
|
||||||
metrics := make([]richMetrics, len(value.Runs))
|
metrics := make([]richMetrics, len(value.Runs))
|
||||||
result := richLayout{anchors: make([]int, len(value.Runs)), bounds: Box{W: width}}
|
result := richLayout{anchors: make([]int, len(value.Runs))}
|
||||||
owners := make([]int, 0, value.Len())
|
owners := make([]int, 0, value.Len())
|
||||||
for i, run := range value.Runs {
|
for i, run := range value.Runs {
|
||||||
font, err := e.editorFont(run.Format.Font)
|
font, err := e.editorFont(run.Format.Font)
|
||||||
@@ -205,7 +205,12 @@ func (e *Editor) layoutRichText(value RichText, width float64) (richLayout, erro
|
|||||||
if err := richPositionSpans(spans, steps, local, x); err != nil {
|
if err := richPositionSpans(spans, steps, local, x); err != nil {
|
||||||
return richLayout{}, err
|
return richLayout{}, err
|
||||||
}
|
}
|
||||||
result.bounds = richUnion(result.bounds, Box{X: x, Y: y, H: height})
|
lineBounds := Box{X: x, Y: y, H: height}
|
||||||
|
if result.bounds.H == 0 {
|
||||||
|
result.bounds = lineBounds
|
||||||
|
} else {
|
||||||
|
result.bounds = richUnion(result.bounds, lineBounds)
|
||||||
|
}
|
||||||
for _, span := range spans {
|
for _, span := range spans {
|
||||||
format := value.Runs[span.owner].Format
|
format := value.Runs[span.owner].Format
|
||||||
for _, glyph := range span.glyphs {
|
for _, glyph := range span.glyphs {
|
||||||
@@ -291,6 +296,9 @@ func (e *Editor) layoutRichText(value RichText, width float64) (richLayout, erro
|
|||||||
if !finite(result.bounds.X) || !finite(result.bounds.Y) || !finite(result.bounds.W) || !finite(result.bounds.H) || result.bounds.H <= 0 {
|
if !finite(result.bounds.X) || !finite(result.bounds.Y) || !finite(result.bounds.W) || !finite(result.bounds.H) || result.bounds.H <= 0 {
|
||||||
return richLayout{}, fmt.Errorf("rich text layout overflow")
|
return richLayout{}, fmt.Errorf("rich text layout overflow")
|
||||||
}
|
}
|
||||||
|
if result.bounds.W == 0 {
|
||||||
|
result.bounds.W = min(width, value.Runs[0].Format.Size)
|
||||||
|
}
|
||||||
for i, anchor := range result.anchors {
|
for i, anchor := range result.anchors {
|
||||||
if anchor >= 0 {
|
if anchor >= 0 {
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in new issue
Block a user