mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-05 19:30:30 +08:00
Field appearance alignment refinements with some options.
This commit is contained in:
parent
bc6391200a
commit
817d0dc805
@ -39,16 +39,23 @@ type AppearanceStyle struct {
|
|||||||
BorderColor model.PdfColor
|
BorderColor model.PdfColor
|
||||||
FillColor model.PdfColor
|
FillColor model.PdfColor
|
||||||
|
|
||||||
|
// Multiplier for lineheight for multi line text.
|
||||||
|
MultilineLineHeight float64
|
||||||
|
MultilineVAlignMiddle bool // Defaults to top.
|
||||||
|
|
||||||
|
// Visual guide checking alignment of field contents (debugging).
|
||||||
|
DrawAlignmentReticle bool
|
||||||
|
|
||||||
// Allow field MK appearance characteristics to override style settings.
|
// Allow field MK appearance characteristics to override style settings.
|
||||||
AllowMK bool
|
AllowMK bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
type quadding int
|
||||||
defaultAutoFontSizeFraction = 0.818
|
|
||||||
defaultCheckmarkGlyph = "a20"
|
const (
|
||||||
defaultBorderSize = 0.0
|
quaddingLeft quadding = 0
|
||||||
defaultBorderColor = model.NewPdfColorDeviceGray(0)
|
quaddingCenter quadding = 1
|
||||||
defaultFillColor = model.NewPdfColorDeviceGray(1)
|
quaddingRight quadding = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetStyle applies appearance `style` to `fa`.
|
// SetStyle applies appearance `style` to `fa`.
|
||||||
@ -61,13 +68,17 @@ func (fa FieldAppearance) Style() AppearanceStyle {
|
|||||||
if fa.style != nil {
|
if fa.style != nil {
|
||||||
return *fa.style
|
return *fa.style
|
||||||
}
|
}
|
||||||
|
// Default values returned if style not set.
|
||||||
return AppearanceStyle{
|
return AppearanceStyle{
|
||||||
AutoFontSizeFraction: defaultAutoFontSizeFraction,
|
AutoFontSizeFraction: 0.65,
|
||||||
CheckmarkGlyph: defaultCheckmarkGlyph,
|
CheckmarkGlyph: "a20",
|
||||||
BorderSize: defaultBorderSize,
|
BorderSize: 0.0,
|
||||||
BorderColor: defaultBorderColor,
|
BorderColor: model.NewPdfColorDeviceGray(0),
|
||||||
FillColor: defaultFillColor,
|
FillColor: model.NewPdfColorDeviceGray(1),
|
||||||
AllowMK: true,
|
MultilineLineHeight: 1.2,
|
||||||
|
MultilineVAlignMiddle: false,
|
||||||
|
DrawAlignmentReticle: false,
|
||||||
|
AllowMK: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +196,14 @@ func genFieldTextAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFieldT
|
|||||||
if style.BorderSize > 0 {
|
if style.BorderSize > 0 {
|
||||||
drawRect(cc, style, width, height)
|
drawRect(cc, style, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if style.DrawAlignmentReticle {
|
||||||
|
// Alignment reticle.
|
||||||
|
style2 := style
|
||||||
|
style2.BorderSize = 0.2
|
||||||
|
drawAlignmentReticle(cc, style2, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
cc.Add_BMC("Tx")
|
cc.Add_BMC("Tx")
|
||||||
cc.Add_q()
|
cc.Add_q()
|
||||||
// Graphic state changes.
|
// Graphic state changes.
|
||||||
@ -246,6 +265,10 @@ func genFieldTextAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFieldT
|
|||||||
resources.SetFontByName(*fontname, fontobj)
|
resources.SetFontByName(*fontname, fontobj)
|
||||||
}
|
}
|
||||||
encoder := font.Encoder()
|
encoder := font.Encoder()
|
||||||
|
fdescriptor, err := font.GetFontDescriptor()
|
||||||
|
if err != nil {
|
||||||
|
common.Log.Debug("Error: Unable to get font descriptor")
|
||||||
|
}
|
||||||
|
|
||||||
text := ""
|
text := ""
|
||||||
if str, ok := core.GetString(ftxt.V); ok {
|
if str, ok := core.GetString(ftxt.V); ok {
|
||||||
@ -259,9 +282,6 @@ func genFieldTextAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFieldT
|
|||||||
|
|
||||||
lines := []string{text}
|
lines := []string{text}
|
||||||
|
|
||||||
var tx float64
|
|
||||||
tx = 2.0 // Default left margin. // TODO(gunnsth): Add to style options.
|
|
||||||
|
|
||||||
// Handle multi line fields.
|
// Handle multi line fields.
|
||||||
isMultiline := false
|
isMultiline := false
|
||||||
if ftxt.Flags().Has(model.FieldFlagMultiline) {
|
if ftxt.Flags().Has(model.FieldFlagMultiline) {
|
||||||
@ -323,64 +343,123 @@ func genFieldTextAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFieldT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tx float64
|
||||||
|
tx = 2.0
|
||||||
|
|
||||||
// Check if text goes out of bounds, if goes out of bounds, then adjust font size until just within bounds.
|
// Check if text goes out of bounds, if goes out of bounds, then adjust font size until just within bounds.
|
||||||
if fontsize == 0 || autosize && maxLinewidth > 0 && tx+maxLinewidth*fontsize/1000.0 > width {
|
if fontsize == 0 || autosize && maxLinewidth > 0 && tx+maxLinewidth*fontsize/1000.0 > width {
|
||||||
// TODO(gunnsth): Add to style options.
|
// TODO(gunnsth): Add to style options.
|
||||||
fontsize = 0.95 * 1000.0 * (width - tx) / maxLinewidth
|
fontsize = 0.95 * 1000.0 * (width - tx) / maxLinewidth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var alignment quadding = quaddingLeft
|
||||||
// Account for horizontal alignment (quadding).
|
// Account for horizontal alignment (quadding).
|
||||||
{
|
{
|
||||||
quadding := 0 // Default (left aligned).
|
|
||||||
if val, has := core.GetIntVal(ftxt.Q); has {
|
if val, has := core.GetIntVal(ftxt.Q); has {
|
||||||
quadding = val
|
switch val {
|
||||||
}
|
case 0: // Left aligned.
|
||||||
switch quadding {
|
alignment = quaddingLeft
|
||||||
case 0: // Left aligned.
|
case 1: // Centered.
|
||||||
case 1: // Centered.
|
alignment = quaddingCenter
|
||||||
remaining := width - maxLinewidth*fontsize/1000.0
|
case 2: // Right justified.
|
||||||
if remaining > 0 {
|
alignment = quaddingRight
|
||||||
tx = remaining / 2
|
default:
|
||||||
|
common.Log.Debug("ERROR: Unsupported quadding: %d - using left alignment", val)
|
||||||
}
|
}
|
||||||
case 2: // Right justified.
|
|
||||||
remaining := width - maxLinewidth*fontsize/1000.0
|
|
||||||
tx = remaining
|
|
||||||
default:
|
|
||||||
common.Log.Debug("ERROR: Unsupported quadding: %d", quadding)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineheight := 1.0 * fontsize
|
lh := style.MultilineLineHeight
|
||||||
|
|
||||||
|
lineheight := fontsize
|
||||||
|
if isMultiline && textlines > 1 {
|
||||||
|
lineheight = lh * fontsize
|
||||||
|
}
|
||||||
|
|
||||||
|
var fcapheight float64
|
||||||
|
if fdescriptor != nil {
|
||||||
|
fcapheight, err = fdescriptor.GetCapHeight()
|
||||||
|
if err != nil {
|
||||||
|
common.Log.Debug("ERROR: Unable to get font CapHeight: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if int(fcapheight) <= 0 {
|
||||||
|
common.Log.Debug("WARN: CapHeight not available - setting to 1000")
|
||||||
|
fcapheight = 1000
|
||||||
|
}
|
||||||
|
capheight := fcapheight / 1000.0 * fontsize
|
||||||
|
|
||||||
// Vertical alignment.
|
// Vertical alignment.
|
||||||
ty := 2.0
|
ty := 0.0
|
||||||
{
|
{
|
||||||
textheight := float64(textlines) * lineheight
|
textheight := float64(textlines) * lineheight
|
||||||
if autosize && ty+textheight > height {
|
if autosize && ty+textheight > height {
|
||||||
fontsize = 0.95 * (height - ty) / float64(textlines)
|
fontsize = 0.95 * (height - ty) / float64(textlines)
|
||||||
lineheight = 1.0 * fontsize
|
lineheight = fontsize
|
||||||
|
if isMultiline && textlines > 1 {
|
||||||
|
lineheight = lh * fontsize
|
||||||
|
}
|
||||||
|
capheight = fcapheight / 1000.0 * fontsize
|
||||||
textheight = float64(textlines) * lineheight
|
textheight = float64(textlines) * lineheight
|
||||||
}
|
}
|
||||||
|
|
||||||
if height > textheight {
|
if height > textheight {
|
||||||
if len(lines) > 1 {
|
if isMultiline {
|
||||||
a := (height - textheight) / 2.0
|
if style.MultilineVAlignMiddle {
|
||||||
b := a + textheight - lineheight
|
a := (height - textheight) / 2.0
|
||||||
ty = b
|
b := a + textheight - lineheight
|
||||||
|
ty = b
|
||||||
|
} else {
|
||||||
|
// Top.
|
||||||
|
ty = height - lineheight
|
||||||
|
ty -= fontsize * 0.5
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ty = (height - textheight) / 2.0
|
ty = (height - capheight) / 2.0
|
||||||
ty += 1.50 // TODO(gunnsth): Make configurable/part of style parameter.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cc.Add_Tf(*fontname, fontsize)
|
cc.Add_Tf(*fontname, fontsize)
|
||||||
cc.Add_Td(tx, ty)
|
cc.Add_Td(tx, ty)
|
||||||
|
tx0 := tx
|
||||||
|
x := tx
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
|
wLine := 0.0
|
||||||
|
for _, r := range line {
|
||||||
|
glyph, has := encoder.RuneToGlyph(r)
|
||||||
|
if !has {
|
||||||
|
common.Log.Debug("Encoder w/o rune '%c' (%X) - skip", r, r)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
metrics, has := font.GetGlyphCharMetrics(glyph)
|
||||||
|
if !has {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wLine += metrics.Wx
|
||||||
|
}
|
||||||
|
linewidth := wLine / 1000.0 * fontsize
|
||||||
|
remaining := width - linewidth
|
||||||
|
|
||||||
|
var xnew float64
|
||||||
|
switch alignment {
|
||||||
|
case quaddingLeft:
|
||||||
|
xnew = tx0
|
||||||
|
case quaddingCenter:
|
||||||
|
xnew = remaining / 2
|
||||||
|
case quaddingRight:
|
||||||
|
xnew = remaining
|
||||||
|
}
|
||||||
|
tx = xnew - x
|
||||||
|
if tx > 0.0 {
|
||||||
|
cc.Add_Td(tx, 0)
|
||||||
|
}
|
||||||
|
x = xnew
|
||||||
|
|
||||||
cc.Add_Tj(*core.MakeString(line))
|
cc.Add_Tj(*core.MakeString(line))
|
||||||
|
|
||||||
if i < len(lines)-1 {
|
if i < len(lines)-1 {
|
||||||
cc.Add_Td(0, -lineheight)
|
cc.Add_Td(0, -lineheight*lh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,6 +529,12 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
|
|||||||
if style.BorderSize > 0 {
|
if style.BorderSize > 0 {
|
||||||
drawRect(cc, style, width, height)
|
drawRect(cc, style, width, height)
|
||||||
}
|
}
|
||||||
|
if style.DrawAlignmentReticle {
|
||||||
|
// Alignment reticle.
|
||||||
|
style2 := style
|
||||||
|
style2.BorderSize = 0.2
|
||||||
|
drawAlignmentReticle(cc, style2, width, height)
|
||||||
|
}
|
||||||
cc.Add_BMC("Tx")
|
cc.Add_BMC("Tx")
|
||||||
cc.Add_q()
|
cc.Add_q()
|
||||||
// Graphic state changes.
|
// Graphic state changes.
|
||||||
@ -459,9 +544,11 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
|
|||||||
var fontsize float64
|
var fontsize float64
|
||||||
var fontname *core.PdfObjectName
|
var fontname *core.PdfObjectName
|
||||||
var font *model.PdfFont
|
var font *model.PdfFont
|
||||||
|
autosize := true
|
||||||
|
|
||||||
fontsizeDef := height * style.AutoFontSizeFraction
|
fontsizeDef := height * style.AutoFontSizeFraction
|
||||||
for _, op := range *daOps {
|
for _, op := range *daOps {
|
||||||
// TODO: If TF specified and font size is 0, it means we should set on our own based on the Rect.
|
// If TF specified and font size is 0, it means we should set on our own based on the Rect.
|
||||||
if op.Operand == "Tf" && len(op.Params) == 2 {
|
if op.Operand == "Tf" && len(op.Params) == 2 {
|
||||||
if name, ok := core.GetName(op.Params[0]); ok {
|
if name, ok := core.GetName(op.Params[0]); ok {
|
||||||
fontname = name
|
fontname = name
|
||||||
@ -475,8 +562,12 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
|
|||||||
if fontsize == 0 {
|
if fontsize == 0 {
|
||||||
// Use default if zero.
|
// Use default if zero.
|
||||||
fontsize = fontsizeDef
|
fontsize = fontsizeDef
|
||||||
|
} else {
|
||||||
|
// Disable autosize when font size (>0) explicitly specified.
|
||||||
|
autosize = false
|
||||||
}
|
}
|
||||||
op.Params[1] = core.MakeFloat(fontsize)
|
// Skip over (set fontsize in code below).
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
cc.AddOperand(*op)
|
cc.AddOperand(*op)
|
||||||
}
|
}
|
||||||
@ -506,14 +597,79 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
|
|||||||
resources.SetFontByName(*fontname, fontobj)
|
resources.SetFontByName(*fontname, fontobj)
|
||||||
}
|
}
|
||||||
encoder := font.Encoder()
|
encoder := font.Encoder()
|
||||||
|
if encoder == nil {
|
||||||
|
common.Log.Debug("ERROR - Encoder is nil - can expect bad results")
|
||||||
|
}
|
||||||
|
|
||||||
text := ""
|
text := ""
|
||||||
if str, ok := core.GetString(ftxt.V); ok {
|
if str, ok := core.GetString(ftxt.V); ok {
|
||||||
text = str.Decoded()
|
text = str.Decoded()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(gunnsth): Add to style options.
|
cc.Add_Tf(*fontname, fontsize)
|
||||||
ty := 0.26 * height
|
|
||||||
|
// Get max glyph height.
|
||||||
|
maxGlyphWy := 0.0
|
||||||
|
for _, r := range text {
|
||||||
|
if encoder != nil {
|
||||||
|
glyph, has := encoder.RuneToGlyph(r)
|
||||||
|
if !has {
|
||||||
|
common.Log.Debug("ERROR: Rune not found %#v - skipping over", r)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
metrics, found := font.GetGlyphCharMetrics(glyph)
|
||||||
|
if !found {
|
||||||
|
common.Log.Debug("ERROR: Glyph not found in font: %v - skipping over", glyph)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
wy := metrics.Wy
|
||||||
|
if wy <= 0 {
|
||||||
|
wy = metrics.Wx
|
||||||
|
}
|
||||||
|
if wy > maxGlyphWy {
|
||||||
|
maxGlyphWy = wy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if int(maxGlyphWy) == 0 {
|
||||||
|
common.Log.Debug("ERROR: Unable to determine max glyph size - using 1000")
|
||||||
|
maxGlyphWy = 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
fdescriptor, err := font.GetFontDescriptor()
|
||||||
|
if err != nil {
|
||||||
|
common.Log.Debug("Error: Unable to get font descriptor")
|
||||||
|
}
|
||||||
|
var fcapheight float64
|
||||||
|
if fdescriptor != nil {
|
||||||
|
fcapheight, err = fdescriptor.GetCapHeight()
|
||||||
|
if err != nil {
|
||||||
|
common.Log.Debug("ERROR: Unable to get font CapHeight: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if int(fcapheight) <= 0 {
|
||||||
|
common.Log.Debug("WARN: CapHeight not available - setting to 1000")
|
||||||
|
fcapheight = 1000.0
|
||||||
|
}
|
||||||
|
capheight := fcapheight / 1000.0 * fontsize
|
||||||
|
|
||||||
|
// Vertical alignment.
|
||||||
|
ty := 0.0
|
||||||
|
lineheight := 1.0 * fontsize * (maxGlyphWy / 1000.0)
|
||||||
|
{
|
||||||
|
textheight := lineheight
|
||||||
|
// If autosize and going out of bounds, reduce to fit.
|
||||||
|
if autosize && ty+textheight > height {
|
||||||
|
fontsize = 0.95 * (height - ty)
|
||||||
|
lineheight = 1.0 * fontsize
|
||||||
|
textheight = lineheight
|
||||||
|
capheight = fcapheight / 1000.0 * fontsize
|
||||||
|
}
|
||||||
|
|
||||||
|
if height > capheight {
|
||||||
|
ty = (height - capheight) / 2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
cc.Add_Td(0, ty)
|
cc.Add_Td(0, ty)
|
||||||
|
|
||||||
if quadding, has := core.GetIntVal(ftxt.Q); has {
|
if quadding, has := core.GetIntVal(ftxt.Q); has {
|
||||||
@ -613,6 +769,13 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
|
|||||||
drawRect(cc, style, width, height)
|
drawRect(cc, style, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if style.DrawAlignmentReticle {
|
||||||
|
// Alignment reticle.
|
||||||
|
style2 := style
|
||||||
|
style2.BorderSize = 0.2
|
||||||
|
drawAlignmentReticle(cc, style2, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
fontsize := style.AutoFontSizeFraction * height
|
fontsize := style.AutoFontSizeFraction * height
|
||||||
|
|
||||||
checkmetrics, ok := zapfdb.GetGlyphCharMetrics(style.CheckmarkGlyph)
|
checkmetrics, ok := zapfdb.GetGlyphCharMetrics(style.CheckmarkGlyph)
|
||||||
@ -624,10 +787,10 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
|
|||||||
return nil, errors.New("checkmark glyph - charcode mapping not found")
|
return nil, errors.New("checkmark glyph - charcode mapping not found")
|
||||||
}
|
}
|
||||||
checkwidth := checkmetrics.Wx * fontsize / 1000.0
|
checkwidth := checkmetrics.Wx * fontsize / 1000.0
|
||||||
checkheight := checkwidth
|
// TODO: Get bbox of specific glyph that is chosen. Choice of specific value will cause slight
|
||||||
if checkmetrics.Wy > 0 {
|
// deviations for other glyphs, but should be fairly close.
|
||||||
checkheight = checkmetrics.Wy * fontsize / 1000.0
|
fcheckheight := 705.0 // From AFM for code 52.
|
||||||
}
|
checkheight := fcheckheight / 1000.0 * fontsize
|
||||||
|
|
||||||
tx := 2.0
|
tx := 2.0
|
||||||
ty := 1.0
|
ty := 1.0
|
||||||
@ -637,7 +800,6 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
|
|||||||
if checkheight < height {
|
if checkheight < height {
|
||||||
ty = (height - checkheight) / 2.0
|
ty = (height - checkheight) / 2.0
|
||||||
}
|
}
|
||||||
ty += 1.0
|
|
||||||
|
|
||||||
cc.Add_q().
|
cc.Add_q().
|
||||||
Add_g(0).
|
Add_g(0).
|
||||||
@ -753,6 +915,12 @@ func makeComboboxTextXObjForm(width, height float64, text string, style Appearan
|
|||||||
if style.BorderSize > 0 {
|
if style.BorderSize > 0 {
|
||||||
drawRect(cc, style, width, height)
|
drawRect(cc, style, width, height)
|
||||||
}
|
}
|
||||||
|
if style.DrawAlignmentReticle {
|
||||||
|
// Alignment reticle.
|
||||||
|
style2 := style
|
||||||
|
style2.BorderSize = 0.2
|
||||||
|
drawAlignmentReticle(cc, style2, width, height)
|
||||||
|
}
|
||||||
cc.Add_BMC("Tx")
|
cc.Add_BMC("Tx")
|
||||||
cc.Add_q()
|
cc.Add_q()
|
||||||
// Graphic state changes.
|
// Graphic state changes.
|
||||||
@ -915,6 +1083,20 @@ func drawRect(cc *contentstream.ContentCreator, style AppearanceStyle, width, he
|
|||||||
Add_Q()
|
Add_Q()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// drawAlignmentReticle draws the Rect box with a reticle on top for alignment guidance.
|
||||||
|
func drawAlignmentReticle(cc *contentstream.ContentCreator, style AppearanceStyle, width, height float64) {
|
||||||
|
cc.Add_q().
|
||||||
|
Add_re(0, 0, width, height).
|
||||||
|
Add_re(0, height/2, width, height/2).
|
||||||
|
Add_re(0, 0, width, height).
|
||||||
|
Add_re(width/2, 0, width/2, height).
|
||||||
|
Add_w(style.BorderSize).
|
||||||
|
SetStrokingColor(style.BorderColor).
|
||||||
|
SetNonStrokingColor(style.FillColor).
|
||||||
|
Add_B().
|
||||||
|
Add_Q()
|
||||||
|
}
|
||||||
|
|
||||||
// Apply appearance characteristics from an MK dictionary `mkDict` to appearance `style`.
|
// Apply appearance characteristics from an MK dictionary `mkDict` to appearance `style`.
|
||||||
// `font` is necessary when the "normal caption" (CA) field is specified (checkboxes).
|
// `font` is necessary when the "normal caption" (CA) field is specified (checkboxes).
|
||||||
func (style *AppearanceStyle) applyAppearanceCharacteristics(mkDict *core.PdfObjectDictionary, bsDict *core.PdfObjectDictionary, font *model.PdfFont) error {
|
func (style *AppearanceStyle) applyAppearanceCharacteristics(mkDict *core.PdfObjectDictionary, bsDict *core.PdfObjectDictionary, font *model.PdfFont) error {
|
||||||
|
@ -27,6 +27,22 @@ type PdfFont struct {
|
|||||||
context fonts.Font // The underlying font: Type0, Type1, Truetype, etc..
|
context fonts.Font // The underlying font: Type0, Type1, Truetype, etc..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFontDescriptor returns the font descriptor for `font`.
|
||||||
|
func (font PdfFont) GetFontDescriptor() (*PdfFontDescriptor, error) {
|
||||||
|
switch t := font.context.(type) {
|
||||||
|
case *pdfFontSimple:
|
||||||
|
return t.fontDescriptor, nil
|
||||||
|
case *pdfFontType0:
|
||||||
|
return t.fontDescriptor, nil
|
||||||
|
case *pdfCIDFontType0:
|
||||||
|
return t.fontDescriptor, nil
|
||||||
|
case *pdfCIDFontType2:
|
||||||
|
return t.fontDescriptor, nil
|
||||||
|
}
|
||||||
|
common.Log.Debug("ERROR: Cannot get font descriptor for font type %t (%s)", font, font)
|
||||||
|
return nil, errors.New("fontdescriptor not found")
|
||||||
|
}
|
||||||
|
|
||||||
// String returns a string that describes `font`.
|
// String returns a string that describes `font`.
|
||||||
func (font PdfFont) String() string {
|
func (font PdfFont) String() string {
|
||||||
enc := ""
|
enc := ""
|
||||||
@ -650,6 +666,21 @@ type PdfFontDescriptor struct {
|
|||||||
container *core.PdfIndirectObject
|
container *core.PdfIndirectObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDescent returns the Descent of the font `descriptor`.
|
||||||
|
func (descriptor *PdfFontDescriptor) GetDescent() (float64, error) {
|
||||||
|
return core.GetNumberAsFloat(descriptor.Descent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAscent returns the Ascent of the font `descriptor`.
|
||||||
|
func (descriptor *PdfFontDescriptor) GetAscent() (float64, error) {
|
||||||
|
return core.GetNumberAsFloat(descriptor.Ascent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCapHeight returns the CapHeight of the font `descriptor`.
|
||||||
|
func (descriptor *PdfFontDescriptor) GetCapHeight() (float64, error) {
|
||||||
|
return core.GetNumberAsFloat(descriptor.CapHeight)
|
||||||
|
}
|
||||||
|
|
||||||
// String returns a string describing the font descriptor.
|
// String returns a string describing the font descriptor.
|
||||||
func (descriptor *PdfFontDescriptor) String() string {
|
func (descriptor *PdfFontDescriptor) String() string {
|
||||||
parts := []string{}
|
parts := []string{}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user