1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-28 01:55:24 +00:00

font format: refactor: moved font glyph into new package

This commit is contained in:
M. Sz 2021-02-18 21:05:16 +01:00
parent aeef2d5c4b
commit b75f82fc8c
3 changed files with 94 additions and 82 deletions

View File

@ -0,0 +1,73 @@
// Package d2fontglyph represents a single font glyph
package d2fontglyph
// Create creates a new font glyph
func Create(frame, width, height int) *FontGlyph {
// nolint:gomnd // thes bytes are constant
// comes from https://d2mods.info/forum/viewtopic.php?t=42044
result := &FontGlyph{
unknown1: []byte{0, 0},
unknown2: []byte{1, 0, 0},
unknown3: []byte{0, 0, 0, 0, 0},
frame: frame,
width: width,
height: height,
}
return result
}
// FontGlyph represents a single font glyph
type FontGlyph struct {
unknown1 []byte
unknown2 []byte
unknown3 []byte
frame int
width int
height int
}
// SetSize sets glyph's size to w, h
func (fg *FontGlyph) SetSize(w, h int) {
fg.width, fg.height = w, h
}
// Size returns glyph's size
func (fg *FontGlyph) Size() (w, h int) {
return fg.width, fg.height
}
// Width returns font width
func (fg *FontGlyph) Width() int {
return fg.width
}
// Height returns glyph's height
func (fg *FontGlyph) Height() int {
return fg.height
}
// SetFrameIndex sets frame index to idx
func (fg *FontGlyph) SetFrameIndex(idx int) {
fg.frame = idx
}
// FrameIndex returns glyph's frame
func (fg *FontGlyph) FrameIndex() int {
return fg.frame
}
// Unknown1 returns unknowns bytes
func (fg *FontGlyph) Unknown1() []byte {
return fg.unknown1
}
// Unknown2 returns unknowns bytes
func (fg *FontGlyph) Unknown2() []byte {
return fg.unknown2
}
// Unknown3 returns unknowns bytes
func (fg *FontGlyph) Unknown3() []byte {
return fg.unknown3
}

View File

@ -1,17 +0,0 @@
package d2font
// NewFontGlyph creates a new font glyph
func NewFontGlyph(frame, width, height int) *FontGlyph {
// nolint:gomnd // thes bytes are constant
// comes from https://d2mods.info/forum/viewtopic.php?t=42044
result := &FontGlyph{
unknown1: []byte{0, 0},
unknown2: []byte{1, 0, 0},
unknown3: []byte{0, 0, 0, 0, 0},
frame: frame,
width: width,
height: height,
}
return result
}

View File

@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2font/d2fontglyph"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2math"
) )
@ -22,42 +23,12 @@ const (
unknown3BytesCount = 4 unknown3BytesCount = 4
) )
// FontGlyph represents a single font glyph
type FontGlyph struct {
unknown1 []byte
unknown2 []byte
unknown3 []byte
frame int
width int
height int
}
// SetSize sets glyph's size to w, h
func (fg *FontGlyph) SetSize(w, h int) {
fg.width, fg.height = w, h
}
// Size returns glyph's size
func (fg *FontGlyph) Size() (w, h int) {
return fg.width, fg.height
}
// SetFrameIndex sets frame index to idx
func (fg *FontGlyph) SetFrameIndex(idx int) {
fg.frame = idx
}
// FrameIndex returns glyph's frame
func (fg *FontGlyph) FrameIndex() int {
return fg.frame
}
// Font represents a displayable font // Font represents a displayable font
type Font struct { type Font struct {
unknownHeaderBytes []byte unknownHeaderBytes []byte
sheet d2interface.Animation sheet d2interface.Animation
table []byte table []byte
Glyphs map[rune]*FontGlyph Glyphs map[rune]*d2fontglyph.FontGlyph
color color.Color color color.Color
} }
@ -100,7 +71,7 @@ func (f *Font) SetBackground(sheet d2interface.Animation) {
_, h := f.sheet.GetFrameBounds() _, h := f.sheet.GetFrameBounds()
for i := range f.Glyphs { for i := range f.Glyphs {
f.Glyphs[i].SetSize(f.Glyphs[i].width, h) f.Glyphs[i].SetSize(f.Glyphs[i].Width(), h)
} }
} }
@ -123,8 +94,8 @@ func (f *Font) GetTextMetrics(text string) (width, height int) {
lineWidth = 0 lineWidth = 0
lineHeight = 0 lineHeight = 0
} else if glyph, ok := f.Glyphs[c]; ok { } else if glyph, ok := f.Glyphs[c]; ok {
lineWidth += glyph.width lineWidth += glyph.Width()
lineHeight = d2math.MaxInt(lineHeight, glyph.height) lineHeight = d2math.MaxInt(lineHeight, glyph.Height())
} }
} }
@ -152,16 +123,16 @@ func (f *Font) RenderText(text string, target d2interface.Surface) error {
continue continue
} }
if err := f.sheet.SetCurrentFrame(glyph.frame); err != nil { if err := f.sheet.SetCurrentFrame(glyph.FrameIndex()); err != nil {
return err return err
} }
f.sheet.Render(target) f.sheet.Render(target)
lineHeight = d2math.MaxInt(lineHeight, glyph.height) lineHeight = d2math.MaxInt(lineHeight, glyph.Height())
lineLength++ lineLength++
target.PushTranslation(glyph.width, 0) target.PushTranslation(glyph.Width(), 0)
} }
target.PopN(lineLength) target.PopN(lineLength)
@ -174,7 +145,7 @@ func (f *Font) RenderText(text string, target d2interface.Surface) error {
} }
func (f *Font) initGlyphs(sr *d2datautils.StreamReader) error { func (f *Font) initGlyphs(sr *d2datautils.StreamReader) error {
glyphs := make(map[rune]*FontGlyph) glyphs := make(map[rune]*d2fontglyph.FontGlyph)
for i := 12; i < len(f.table); i += 14 { for i := 12; i < len(f.table); i += 14 {
code, err := sr.ReadUInt16() code, err := sr.ReadUInt16()
@ -182,48 +153,33 @@ func (f *Font) initGlyphs(sr *d2datautils.StreamReader) error {
return err return err
} }
var glyph FontGlyph
// two bytes of 0 // two bytes of 0
glyph.unknown1, err = sr.ReadBytes(unknown1BytesCount) sr.SkipBytes(unknown1BytesCount)
if err != nil {
return err
}
width, err := sr.ReadByte() width, err := sr.ReadByte()
if err != nil { if err != nil {
return err return err
} }
glyph.width = int(width)
height, err := sr.ReadByte() height, err := sr.ReadByte()
if err != nil { if err != nil {
return err return err
} }
glyph.height = int(height)
// 1, 0, 0 // 1, 0, 0
glyph.unknown2, err = sr.ReadBytes(unknown2BytesCount) sr.SkipBytes(unknown2BytesCount)
if err != nil {
return err
}
frame, err := sr.ReadUInt16() frame, err := sr.ReadUInt16()
if err != nil { if err != nil {
return err return err
} }
glyph.frame = int(frame)
// 1, 0, 0, character code repeated, and further 0. // 1, 0, 0, character code repeated, and further 0.
glyph.unknown3, err = sr.ReadBytes(unknown3BytesCount) sr.SkipBytes(unknown3BytesCount)
if err != nil {
return err
}
glyphs[rune(code)] = &glyph glyph := d2fontglyph.Create(int(width), int(height), int(frame))
glyphs[rune(code)] = glyph
} }
f.Glyphs = glyphs f.Glyphs = glyphs
@ -240,12 +196,12 @@ func (f *Font) Marshal() []byte {
for c, i := range f.Glyphs { for c, i := range f.Glyphs {
sw.PushUint16(uint16(c)) sw.PushUint16(uint16(c))
sw.PushBytes(i.unknown1...) sw.PushBytes(i.Unknown1()...)
sw.PushBytes(byte(i.width)) sw.PushBytes(byte(i.Width()))
sw.PushBytes(byte(i.height)) sw.PushBytes(byte(i.Height()))
sw.PushBytes(i.unknown2...) sw.PushBytes(i.Unknown2()...)
sw.PushUint16(uint16(i.frame)) sw.PushUint16(uint16(i.FrameIndex()))
sw.PushBytes(i.unknown3...) sw.PushBytes(i.Unknown3()...)
} }
return sw.GetBytes() return sw.GetBytes()