mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
1 parent
6d782de471
commit
f5463b9479
17 files changed
+68
-46
No files matched your search
@@ -227,19 +227,19 @@
|
||||
<details id="objectGradientFields" hidden>
|
||||
<summary>渐变</summary>
|
||||
<div class="form-pair">
|
||||
<div class="form-row"><label for="gradientTarget">作用</label><select id="gradientTarget"><option value="fill">填充</option><option value="stroke">描边</option></select></div>
|
||||
<div class="form-row"><label for="gradientTarget">应用</label><select id="gradientTarget"><option value="fill">填充</option><option value="stroke">描边</option></select></div>
|
||||
<div class="form-row"><label for="gradientKind">类型</label><select id="gradientKind"><option value="keep">保持</option><option value="linear">线性</option><option value="radial">径向</option></select></div>
|
||||
</div>
|
||||
<div id="gradientControls" hidden>
|
||||
<div class="form-row"><label for="gradientAngle">角度</label><div class="form-unit"><input id="gradientAngle" type="number" step="any" value="0"><span>°</span></div></div>
|
||||
<div class="gradient-stop-row gradient-stop-head"><span>颜色</span><span>位置%</span><span>透明%</span><span></span></div>
|
||||
<div id="gradientStops"></div>
|
||||
<button id="gradientAdd" class="small-button" type="button" title="添加色标" aria-label="添加色标">+</button>
|
||||
<button id="gradientAdd" class="icon-button" type="button" title="添加色标" aria-label="添加色标">+</button>
|
||||
</div>
|
||||
</details>
|
||||
<details id="objectPatternFields" hidden>
|
||||
<summary>图案</summary>
|
||||
<div class="form-row"><label for="patternTarget">作用</label><select id="patternTarget"><option value="fill">填充</option><option value="stroke">描边</option></select></div>
|
||||
<div class="form-row"><label for="patternTarget">应用</label><select id="patternTarget"><option value="fill">填充</option><option value="stroke">描边</option></select></div>
|
||||
<div class="form-pair">
|
||||
<div class="form-row"><label for="patternWidth">宽度</label><div class="form-unit"><input id="patternWidth" type="number" min="0" step="any"><span>mm</span></div></div>
|
||||
<div class="form-row"><label for="patternHeight">高度</label><div class="form-unit"><input id="patternHeight" type="number" min="0" step="any"><span>mm</span></div></div>
|
||||
@@ -437,7 +437,7 @@
|
||||
<label class="form-row"><span>标题</span><input id="infoTitle" type="text" autofocus></label>
|
||||
<label class="form-row"><span>主题</span><input id="infoSubject" type="text"></label>
|
||||
<label class="form-row"><span>作者</span><input id="infoAuthor" type="text"></label>
|
||||
<details class="info-custom"><summary>扩展</summary><div id="infoCustomRows"></div><button id="infoCustomAdd" class="small-button" type="button" title="添加字段" aria-label="添加字段">+</button></details>
|
||||
<details class="info-custom"><summary>扩展</summary><div id="infoCustomRows"></div><button id="infoCustomAdd" class="icon-button" type="button" title="添加字段" aria-label="添加字段">+</button></details>
|
||||
<div class="form-actions"><div id="infoStatus" class="form-status" role="status"></div><button id="infoCancel" class="button" type="button">取消</button><button class="button" type="submit">确定</button></div>
|
||||
</form>
|
||||
</dialog>
|
||||
@@ -559,8 +559,8 @@
|
||||
<div class="form-row"><span>预览</span><div class="seal-position-options"><button id="signPick" class="button" type="button">定位</button><label><input id="signKeepRatio" type="checkbox" checked>等比</label></div></div>
|
||||
<div class="form-row"><label for="signPlacement">位置</label><select id="signPlacement"><option value="normal">页面</option><option value="seam">骑缝</option></select></div>
|
||||
<div class="form-row"><label for="signPages">页码</label><input id="signPages" type="text" autocomplete="off" spellcheck="false"></div>
|
||||
<div class="form-row"><label for="signX">横坐标</label><div class="form-unit"><input id="signX" type="number" min="0" step="any" value="10" aria-label="横坐标(毫米)"><span>mm</span></div></div>
|
||||
<div class="form-row"><label for="signY">纵坐标</label><div class="form-unit"><input id="signY" type="number" min="0" step="any" value="10" aria-label="纵坐标(毫米)"><span>mm</span></div></div>
|
||||
<div class="form-row"><label for="signX">横向</label><div class="form-unit"><input id="signX" type="number" min="0" step="any" value="10" aria-label="横坐标(毫米)"><span>mm</span></div></div>
|
||||
<div class="form-row"><label for="signY">纵向</label><div class="form-unit"><input id="signY" type="number" min="0" step="any" value="10" aria-label="纵坐标(毫米)"><span>mm</span></div></div>
|
||||
<div class="form-row"><label for="signWidth">宽度</label><div class="form-unit"><input id="signWidth" type="number" min="0.01" step="any" value="40" aria-label="宽度(毫米)"><span>mm</span></div></div>
|
||||
<div class="form-row"><label for="signHeight">高度</label><div class="form-unit"><input id="signHeight" type="number" min="0.01" step="any" value="40" aria-label="高度(毫米)"><span>mm</span></div></div>
|
||||
</div>
|
||||
@@ -788,7 +788,7 @@
|
||||
</section>
|
||||
<section class="doc-font-panel" aria-labelledby="docFontPanelTitle">
|
||||
<div class="panel-row">
|
||||
<div id="docFontPanelTitle" class="panel-title compact">OFD 字体</div>
|
||||
<div id="docFontPanelTitle" class="panel-title compact">文档字体</div>
|
||||
<span id="docFontSummary" class="count-pill">0</span>
|
||||
</div>
|
||||
<div id="docFontList" class="doc-font-list"></div>
|
||||
|
||||
+24
-6
@@ -1214,7 +1214,7 @@ button:not(:disabled):hover {
|
||||
}
|
||||
|
||||
.info-custom-row input,
|
||||
.gradient-stop-row input,
|
||||
.gradient-stop-row input[type="number"],
|
||||
.structure-attribute > input,
|
||||
.form-row input[type="text"],
|
||||
.form-row input[type="password"],
|
||||
@@ -1260,8 +1260,8 @@ button:not(:disabled):hover {
|
||||
.info-custom-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) var(--control-height);
|
||||
gap: 6px;
|
||||
margin: 6px 0;
|
||||
gap: 8px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
#infoCustomRows > :first-child {
|
||||
@@ -1271,8 +1271,8 @@ button:not(:disabled):hover {
|
||||
.gradient-stop-row {
|
||||
display: grid;
|
||||
grid-template-columns: 44px minmax(0, 1fr) minmax(0, 1fr) var(--control-height);
|
||||
gap: 6px;
|
||||
margin: 6px 0;
|
||||
gap: 8px;
|
||||
margin: 8px 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -1280,9 +1280,27 @@ button:not(:disabled):hover {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.gradient-stop-head,
|
||||
#gradientStops {
|
||||
overflow-y: auto;
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
#gradientStops {
|
||||
max-height: 180px;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
#gradientStops > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#gradientStops > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.gradient-stop-row .color-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#infoCustomRows :focus-visible,
|
||||
|
||||
@@ -887,7 +887,7 @@ function addCustomDataRow(field = {Name: "", Value: ""}, sourceIndex) {
|
||||
}
|
||||
const remove = document.createElement("button");
|
||||
remove.type = "button";
|
||||
remove.className = "small-button";
|
||||
remove.className = "icon-button";
|
||||
remove.textContent = "×";
|
||||
remove.title = "删除字段";
|
||||
remove.setAttribute("aria-label", "删除字段");
|
||||
@@ -2045,6 +2045,7 @@ function addGradientStop(position, color, transparency, source) {
|
||||
for (const [type, value, label] of [["color", color, "色标颜色"], ["number", position, "色标位置"], ["number", transparency, "色标透明度"]]) {
|
||||
const input = document.createElement("input");
|
||||
input.type = type;
|
||||
if (type === "color") input.className = "color-input";
|
||||
input.value = value;
|
||||
input.disabled = el.gradientKind.value === "keep";
|
||||
input.setAttribute("aria-label", label);
|
||||
@@ -2054,7 +2055,7 @@ function addGradientStop(position, color, transparency, source) {
|
||||
}
|
||||
const remove = document.createElement("button");
|
||||
remove.type = "button";
|
||||
remove.className = "small-button";
|
||||
remove.className = "icon-button";
|
||||
remove.textContent = "×";
|
||||
remove.title = "删除色标";
|
||||
remove.setAttribute("aria-label", "删除色标");
|
||||
@@ -5619,8 +5620,8 @@ function renderStyleResourceSettings(kind) {
|
||||
}
|
||||
settingsField(content, "斜体", "Italic", value.Italic, "checkbox");
|
||||
settingsSelect(content, "端点", "Cap", [["", "继承"], ["Butt", "平头"], ["Round", "圆头"], ["Square", "方头"]], value.Cap || "");
|
||||
settingsSelect(content, "连接", "Join", [["", "继承"], ["Miter", "尖角"], ["Round", "圆角"], ["Bevel", "斜角"]], value.Join || "");
|
||||
settingsField(content, "虚线", "DashPattern", value.DashPattern || "");
|
||||
settingsSelect(content, "转角", "Join", [["", "继承"], ["Miter", "尖角"], ["Round", "圆角"], ["Bevel", "斜角"]], value.Join || "");
|
||||
settingsField(content, "间隔", "DashPattern", value.DashPattern || "").title = "虚线间隔";
|
||||
settingsField(content, "偏移", "DashOffset", value.DashOffset ?? "", "number", "mm");
|
||||
for (const [key, label] of [["FillColor", "填充"], ["StrokeColor", "描边"]]) {
|
||||
settingsSelect(content, label, key + "Mode", [["keep", "原有"], ["inherit", "继承"], ["solid", "颜色"]], "keep");
|
||||
@@ -5641,7 +5642,7 @@ function renderStyleResourceSettings(kind) {
|
||||
if (kind === "ColorSpace") {
|
||||
settingsSelect(binding, "应用", "PaintTarget", [["fill", "填充"], ["stroke", "描边"]], "fill");
|
||||
settingsSelect(binding, "方式", "PaintMode", [["value", "分量"], ["index", "索引"]], "value");
|
||||
settingsField(binding, "颜色值", "PaintValue", value.Type === "CMYK" ? `0 0 0 ${2 ** (value.BitsPerComponent || 8) - 1}` : value.Type === "GRAY" ? "0" : "0 0 0");
|
||||
settingsField(binding, "色值", "PaintValue", value.Type === "CMYK" ? `0 0 0 ${2 ** (value.BitsPerComponent || 8) - 1}` : value.Type === "GRAY" ? "0" : "0 0 0");
|
||||
}
|
||||
const apply = settingsButton("应用", () => applyStyleResource(kind), !objects.value, "Apply", group.actions);
|
||||
const unbind = kind === "DrawParam" ? settingsButton("解绑", () => applyStyleResource(kind, true), !objects.value, "Unbind", group.actions) : null;
|
||||
@@ -5784,7 +5785,8 @@ function renderTemplateSettings() {
|
||||
settingsElements.Content.append(source);
|
||||
}
|
||||
settingsPages(source, "SourcePage", settings.page);
|
||||
document.querySelector("#settingsSourcePage").closest("label").firstElementChild.textContent = "来源页";
|
||||
document.querySelector("#settingsSourcePage").closest("label").firstElementChild.textContent = "来源";
|
||||
document.querySelector("#settingsSourcePage").setAttribute("aria-label", "来源页");
|
||||
const write = async (operation, order = 0) => {
|
||||
if (operation === "replace" && !window.confirm("替换模板内容?当前文档中引用此模板的页面将同步更新。")) return;
|
||||
const selected = settings.selected;
|
||||
@@ -6626,7 +6628,7 @@ function updateSignPlacement() {
|
||||
input.disabled = !stamp;
|
||||
input.required = stamp;
|
||||
}
|
||||
document.querySelector('label[for="signX"]').textContent = el.signPlacement.value === "seam" ? "右侧内缩" : "横坐标";
|
||||
document.querySelector('label[for="signX"]').textContent = el.signPlacement.value === "seam" ? "右侧内缩" : "横向";
|
||||
el.signX.setAttribute("aria-label", el.signPlacement.value === "seam" ? "右侧内缩(毫米)" : "横坐标(毫米)");
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ type OpenOptions struct {
|
||||
// FontFile 字体文件
|
||||
type FontFile = ofdgo.FontFile
|
||||
|
||||
// FontInfo OFD字体信息
|
||||
// FontInfo 文档字体信息
|
||||
type FontInfo = ofdgo.FontInfo
|
||||
|
||||
// Session WebUI文档会话
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ package ofdgo
|
||||
// defaultPathLineWidth 为默认描边宽度,单位为毫米
|
||||
const defaultPathLineWidth = 0.353
|
||||
|
||||
// defaultMiterLimit 为默认尖角限制
|
||||
// defaultMiterLimit 为默认尖角截断值
|
||||
const defaultMiterLimit = 3.528
|
||||
|
||||
// mergeGraphicObjectAlpha 合并图形对象透明度
|
||||
|
||||
@@ -109,7 +109,7 @@ func (e *Editor) AddColorSpace(space ColorSpace, profile []byte) (string, error)
|
||||
|
||||
// GradientStops 解析当前文档的渐变分段,保留顺序并合并透明度
|
||||
// 入参: segments 渐变分段, alpha 外层透明度
|
||||
// 返回: []ColorStop 后端无关的色标, error 颜色解析错误
|
||||
// 返回: []ColorStop 后端无关的渐变色标, error 颜色解析错误
|
||||
func (e *Editor) GradientStops(segments []ShdSegment, alpha *int) ([]ColorStop, error) {
|
||||
positions := gradientPositions(segments)
|
||||
stops := make([]ColorStop, len(segments))
|
||||
|
||||
@@ -175,7 +175,7 @@ func (e *Editor) wrapCompositePath(renderer *Renderer, node *editorCompositeNode
|
||||
return e.vectorInstance(renderer, []*editorCompositeNode{node})
|
||||
}
|
||||
|
||||
// isolateCompositeStyle 固定对象的绘制参数,避免目标容器改变颜色、虚线和线帽
|
||||
// isolateCompositeStyle 固定对象的绘制参数,避免目标容器改变颜色、虚线和端点样式
|
||||
// 入参: node 页面坐标中的对象节点
|
||||
// 返回: error 错误信息
|
||||
func (e *Editor) isolateCompositeStyle(node *editorCompositeNode) error {
|
||||
|
||||
@@ -443,7 +443,7 @@ func resourceColorNode(node *editorXML) bool {
|
||||
|
||||
// validateResourceColors 校验显式及默认颜色空间的既有颜色,防止位深或调色板更新使引用失效
|
||||
// 入参: ctx 取消上下文, catalog 当前资源目录, space 替换后的颜色空间
|
||||
// 返回: error 不兼容的颜色值或调色板索引
|
||||
// 返回: error 不兼容的色值或调色板索引
|
||||
func validateResourceColors(ctx context.Context, catalog *resourceCatalog, space ColorSpace) error {
|
||||
doc, err := catalog.scan.reader.DocContext(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
// ObjectStyle 对象外观,nil字段保持原值,颜色的Alpha为nil时保留原颜色透明度
|
||||
// StyleObjects使用对象坐标毫米,StyleCompositeObjects的线宽、虚线长度及偏移使用页面毫米
|
||||
// Cap为端点样式,Join为转角样式,MiterLimit为尖角截断值,DashPattern为虚线间隔序列
|
||||
type ObjectStyle struct {
|
||||
Alpha *int
|
||||
Fill *bool
|
||||
|
||||
+4
-4
@@ -35,7 +35,7 @@ const (
|
||||
FontStatusMissing = "missing"
|
||||
)
|
||||
|
||||
// FontInfo OFD字体诊断信息,MatchedFace为实际匹配字体及原文件中的零起始索引,无法读取时为空
|
||||
// FontInfo 文档字体诊断信息,MatchedFace为实际匹配字体及原文件中的零起始索引,无法读取时为空
|
||||
type FontInfo struct {
|
||||
ID string `json:"id"`
|
||||
FontName string `json:"fontName"`
|
||||
@@ -141,7 +141,7 @@ func (r *Reader) fontDefinition(id string) *Font {
|
||||
return font
|
||||
}
|
||||
|
||||
// FontInfos 获取OFD字体诊断信息
|
||||
// FontInfos 获取文档字体诊断信息
|
||||
// 返回: []FontInfo 字体诊断列表, error 错误信息
|
||||
func (r *Renderer) FontInfos() ([]FontInfo, error) {
|
||||
scanner, err := r.ScanFontInfos()
|
||||
@@ -202,7 +202,7 @@ func (s *FontInfoScanner) Infos() ([]FontInfo, error) {
|
||||
return s.renderer.fontInfos(s.usage)
|
||||
}
|
||||
|
||||
// FontInfosFromPages 从页面内容获取OFD字体诊断信息
|
||||
// FontInfosFromPages 从页面内容获取文档字体诊断信息
|
||||
// 入参: pages 页面内容列表
|
||||
// 返回: []FontInfo 字体诊断列表, error 错误信息
|
||||
func (r *Renderer) FontInfosFromPages(pages []*PageContent) ([]FontInfo, error) {
|
||||
@@ -291,7 +291,7 @@ func (r *Renderer) fontInfoDocument() (*Document, error) {
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
// fontInfos 获取OFD字体诊断信息
|
||||
// fontInfos 获取文档字体诊断信息
|
||||
// 入参: usage 字体使用次数
|
||||
// 返回: []FontInfo 字体诊断列表, error 错误信息
|
||||
func (r *Renderer) fontInfos(usage map[string]int) ([]FontInfo, error) {
|
||||
|
||||
@@ -26,7 +26,7 @@ type geometryPolyline struct {
|
||||
direction Point
|
||||
}
|
||||
|
||||
// Stroke 将曲线、虚线及线帽连接转换为非零填充轮廓
|
||||
// Stroke 按端点和转角样式将曲线、虚线转换为非零填充轮廓
|
||||
// 曲线按Tolerance展开,默认误差为0.001毫米,重叠轮廓保持同向绕数
|
||||
// 结果未做布尔整理,按非零规则填充,区域运算需能处理重叠子路径的后端
|
||||
// 入参: options 描边样式
|
||||
@@ -283,7 +283,7 @@ func (line geometryPolyline) dash(pattern []float64, total, offset float64) ([]g
|
||||
|
||||
// stroke 追加同向矩形、连接楔形及圆盘组成的非零填充区域
|
||||
// 入参: result 已有轮廓, options 描边样式
|
||||
// 返回: GeometryPath 填充轮廓, error 不支持的退化方形线帽
|
||||
// 返回: GeometryPath 填充轮廓, error 不支持的退化方头端点
|
||||
func (line geometryPolyline) stroke(result GeometryPath, options StrokeOptions) (GeometryPath, error) {
|
||||
half := options.Width / 2
|
||||
polygon := func(points ...Point) {
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ func (r *Renderer) ResolveColor(value string, index *int, space string, alpha *i
|
||||
|
||||
// GradientStops 解析OFD渐变分段的位置与透明度,返回独立数据并保留原分段顺序
|
||||
// 入参: segments 渐变分段, alpha 透明度
|
||||
// 返回: []ColorStop 后端无关的渐变分段
|
||||
// 返回: []ColorStop 后端无关的渐变色标
|
||||
func (r *Renderer) GradientStops(segments []ShdSegment, alpha *int) []ColorStop {
|
||||
var gradient []ColorStop
|
||||
positions := gradientPositions(segments)
|
||||
@@ -49,7 +49,7 @@ func (r *Renderer) GradientStops(segments []ShdSegment, alpha *int) []ColorStop
|
||||
}
|
||||
|
||||
// parseColorWithAlpha 解析带透明度的颜色
|
||||
// 入参: value 颜色值, index 调色板索引, space 颜色空间标识, alpha 透明度
|
||||
// 入参: value 色值, index 调色板索引, space 颜色空间标识, alpha 透明度
|
||||
// 返回: color.Color 颜色对象
|
||||
func (r *Renderer) parseColorWithAlpha(value string, index *int, space string, alpha *int) color.Color {
|
||||
kind, values := r.colorComponents(value, index, space)
|
||||
@@ -89,7 +89,7 @@ func (r *Renderer) parseColorWithAlpha(value string, index *int, space string, a
|
||||
}
|
||||
|
||||
// colorComponents 读取颜色空间及归一化分量,保留源位深供渐变插值
|
||||
// 入参: value 颜色值, index 调色板索引, space 颜色空间标识
|
||||
// 入参: value 色值, index 调色板索引, space 颜色空间标识
|
||||
// 返回: string 颜色模型, [4]float64 单位分量
|
||||
func (r *Renderer) colorComponents(value string, index *int, space string) (string, [4]float64) {
|
||||
cs := r.colorDefinition(space)
|
||||
|
||||
@@ -207,7 +207,7 @@ func canvasNativeStroke(geometry GeometryBackend) bool {
|
||||
}
|
||||
|
||||
// canvasStrokeOptions 转换Canvas描边样式,虚线由调用方传入
|
||||
// 入参: width 描边宽度, cap 线帽, join 连接, tolerance 展开误差
|
||||
// 入参: width 线宽, cap 端点样式, join 转角样式, tolerance 展开误差
|
||||
// 返回: StrokeOptions 公共描边样式
|
||||
func canvasStrokeOptions(width float64, cap canvas.Capper, join canvas.Joiner, tolerance float64) StrokeOptions {
|
||||
options := StrokeOptions{Width: width, Cap: "Butt", Join: "Miter", MiterLimit: defaultMiterLimit, Tolerance: tolerance}
|
||||
@@ -274,14 +274,14 @@ func canvasFillClip(clip *canvas.Path) bool {
|
||||
}
|
||||
|
||||
// strokeCanvasPath 将文字和复杂画刷的描边交给配置的几何后端
|
||||
// 入参: path Canvas路径, width 描边宽度, cap 线帽, join 连接
|
||||
// 入参: path Canvas路径, width 线宽, cap 端点样式, join 转角样式
|
||||
// 返回: *canvas.Path 描边轮廓
|
||||
func (r *Renderer) strokeCanvasPath(path *canvas.Path, width float64, cap canvas.Capper, join canvas.Joiner) *canvas.Path {
|
||||
return r.strokeDashedCanvasPath(path, width, cap, join, 0, nil, false)
|
||||
}
|
||||
|
||||
// strokeDashedCanvasPath 通过公共几何后端展开虚线和线帽,保留零长度绘制段
|
||||
// 入参: path 路径, width 线宽, cap 线帽, join 连接, offset 虚线偏移, dashes 虚线数组, fill 是否直接填充或凸窗口裁剪
|
||||
// strokeDashedCanvasPath 通过公共几何后端展开虚线和端点样式,保留零长度绘制段
|
||||
// 入参: path 路径, width 线宽, cap 端点样式, join 转角样式, offset 虚线偏移, dashes 虚线间隔序列, fill 是否直接填充或凸窗口裁剪
|
||||
// 返回: *canvas.Path 描边填充轮廓
|
||||
func (r *Renderer) strokeDashedCanvasPath(path *canvas.Path, width float64, cap canvas.Capper, join canvas.Joiner, offset float64, dashes []float64, fill bool) *canvas.Path {
|
||||
geometry, err := r.Geometry()
|
||||
|
||||
@@ -99,7 +99,7 @@ func (r *boundsRenderer) Size() (float64, float64) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
// RenderPath 收集填充与描边范围,保持线帽、连接和虚线语义
|
||||
// RenderPath 收集填充与描边范围,保持端点、转角和虚线语义
|
||||
// 入参: path 路径, style 绘制样式, m 变换矩阵
|
||||
func (r *boundsRenderer) RenderPath(path *canvas.Path, style canvas.Style, m canvas.Matrix) {
|
||||
if style.HasFill() {
|
||||
|
||||
@@ -49,8 +49,8 @@ func (r *Renderer) parseStrokePaint(strokeColor *StrokeColor, x, y, pageH float6
|
||||
}
|
||||
|
||||
// canvasGradient 将公共颜色节点转换为Canvas渐变
|
||||
// 入参: stops 渐变分段
|
||||
// 返回: canvas.Grad 渐变分段
|
||||
// 入参: stops 渐变色标
|
||||
// 返回: canvas.Grad 渐变色标
|
||||
func canvasGradient(stops []ColorStop) canvas.Grad {
|
||||
var gradient canvas.Grad
|
||||
for _, stop := range stops {
|
||||
|
||||
@@ -75,9 +75,9 @@ func (s *pathStyle) applyStrokeColor(r *Renderer, stroke *StrokeColor, bx, by, p
|
||||
s.strokePaint = r.parseStrokePaint(strokeColorNode, bx, by, pageH)
|
||||
}
|
||||
|
||||
// pathLineCap 转换线帽样式
|
||||
// 入参: cap 线帽名称, fallback 默认线帽
|
||||
// 返回: canvas.Capper 线帽样式
|
||||
// pathLineCap 转换端点样式
|
||||
// 入参: cap 端点样式名称, fallback 默认端点样式
|
||||
// 返回: canvas.Capper 端点样式
|
||||
func pathLineCap(cap string, fallback canvas.Capper) canvas.Capper {
|
||||
switch cap {
|
||||
case "Butt":
|
||||
@@ -90,8 +90,8 @@ func pathLineCap(cap string, fallback canvas.Capper) canvas.Capper {
|
||||
return fallback
|
||||
}
|
||||
|
||||
// applyLineJoin 应用线连接样式及尖角限制
|
||||
// 入参: join 线连接名称, limit 尖角限制, explicit 是否显式指定零截断值
|
||||
// applyLineJoin 应用转角样式及尖角截断值
|
||||
// 入参: join 转角样式名称, limit 尖角截断值, explicit 是否显式指定零截断值
|
||||
func (s *pathStyle) applyLineJoin(join string, limit float64, explicit bool) {
|
||||
if limit > 0 || explicit {
|
||||
s.miterLimit = limit
|
||||
|
||||
@@ -84,6 +84,7 @@ type DrawParams struct {
|
||||
}
|
||||
|
||||
// DrawParam 绘制参数
|
||||
// Cap为端点样式,Join为转角样式,MiterLimit为尖角截断值,DashPattern为虚线间隔序列
|
||||
// MiterLimitSet为true时,零截断值覆盖继承值,否则零值表示未指定
|
||||
type DrawParam struct {
|
||||
ID string `xml:"ID,attr"`
|
||||
|
||||
Reference in new issue
Block a user