package canvas import ( "image" "image/color" "golang.org/x/image/font" "golang.org/x/image/math/fixed" ) // SetFont 设置字体 func (c *Context) SetFont(face font.Face) { c.state.fontFace = face } // SetTextAlign 设置文本对齐 func (c *Context) SetTextAlign(align string) { c.state.textAlign = align } // SetTextBaseline 设置文本基线 func (c *Context) SetTextBaseline(baseline string) { c.state.textBaseline = baseline } // FillText 绘制填充文本 func (c *Context) FillText(text string, x, y float64) { if c.state.fontFace == nil { return } // 应用阴影 if c.state.shadowBlur > 0 || c.state.shadowOffsetX != 0 || c.state.shadowOffsetY != 0 { c.drawTextShadow(text, x, y, true) } c.drawText(text, x, y, true) } // StrokeText 绘制描边文本 func (c *Context) StrokeText(text string, x, y float64) { if c.state.fontFace == nil { return } // 应用阴影 if c.state.shadowBlur > 0 || c.state.shadowOffsetX != 0 || c.state.shadowOffsetY != 0 { c.drawTextShadow(text, x, y, false) } c.drawText(text, x, y, false) } // MeasureText 测量文本宽度 func (c *Context) MeasureText(text string) float64 { if c.state.fontFace == nil { return 0 } width := 0 for _, r := range text { aw, _ := c.state.fontFace.GlyphAdvance(r) width += aw.Round() } return float64(width) } // 绘制文本 func (c *Context) drawText(text string, x, y float64, fill bool) { pt := c.transformPoint(x, y) // 计算文本宽度用于对齐 textWidth := c.MeasureText(text) // 应用对齐 switch c.state.textAlign { case "center": pt.X -= int(textWidth / 2) case "end", "right": pt.X -= int(textWidth) } // 应用基线 metrics := c.state.fontFace.Metrics() switch c.state.textBaseline { case "top": pt.Y += metrics.Ascent.Round() case "middle": pt.Y += (metrics.Ascent + metrics.Descent).Round() / 2 case "bottom": pt.Y += metrics.Descent.Round() } // 创建文本绘制器 drawer := font.Drawer{ Dst: c.img, Face: c.state.fontFace, Dot: fixed.P(pt.X, pt.Y), } // 设置颜色 if fill { switch style := c.state.fillStyle.(type) { case color.Color: drawer.Src = image.NewUniform(c.applyAlpha(style)) case Gradient: drawer.Src = &gradientImage{grad: style, alpha: c.state.globalAlpha} } } else { // 描边文本 - 简单实现,实际应使用路径 switch style := c.state.strokeStyle.(type) { case color.Color: drawer.Src = image.NewUniform(c.applyAlpha(style)) case Gradient: drawer.Src = &gradientImage{grad: style, alpha: c.state.globalAlpha} } } // 绘制文本 if fill { drawer.DrawString(text) } else { // 简单描边实现 - 实际应用中应使用更高级的路径方法 offset := 1 for dx := -offset; dx <= offset; dx++ { for dy := -offset; dy <= offset; dy++ { if dx != 0 || dy != 0 { drawer.Dot = fixed.P(pt.X+dx, pt.Y+dy) drawer.DrawString(text) } } } } } // 绘制文本阴影 func (c *Context) drawTextShadow(text string, x, y float64, fill bool) { // 保存当前状态 c.Save() // 设置阴影样式 shadowStyle := c.state.shadowColor c.SetFillColor(shadowStyle) c.SetStrokeColor(shadowStyle) c.SetGlobalAlpha(0.5 * c.state.globalAlpha) // 阴影透明度 // 应用阴影偏移 x += c.state.shadowOffsetX y += c.state.shadowOffsetY // 绘制阴影文本 if fill { c.FillText(text, x, y) } else { c.StrokeText(text, x, y) } // 恢复状态 c.Restore() }