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"
"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/d2math"
)
@ -22,42 +23,12 @@ const (
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
type Font struct {
unknownHeaderBytes []byte
sheet d2interface.Animation
table []byte
Glyphs map[rune]*FontGlyph
Glyphs map[rune]*d2fontglyph.FontGlyph
color color.Color
}
@ -100,7 +71,7 @@ func (f *Font) SetBackground(sheet d2interface.Animation) {
_, h := f.sheet.GetFrameBounds()
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
lineHeight = 0
} else if glyph, ok := f.Glyphs[c]; ok {
lineWidth += glyph.width
lineHeight = d2math.MaxInt(lineHeight, glyph.height)
lineWidth += glyph.Width()
lineHeight = d2math.MaxInt(lineHeight, glyph.Height())
}
}
@ -152,16 +123,16 @@ func (f *Font) RenderText(text string, target d2interface.Surface) error {
continue
}
if err := f.sheet.SetCurrentFrame(glyph.frame); err != nil {
if err := f.sheet.SetCurrentFrame(glyph.FrameIndex()); err != nil {
return err
}
f.sheet.Render(target)
lineHeight = d2math.MaxInt(lineHeight, glyph.height)
lineHeight = d2math.MaxInt(lineHeight, glyph.Height())
lineLength++
target.PushTranslation(glyph.width, 0)
target.PushTranslation(glyph.Width(), 0)
}
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 {
glyphs := make(map[rune]*FontGlyph)
glyphs := make(map[rune]*d2fontglyph.FontGlyph)
for i := 12; i < len(f.table); i += 14 {
code, err := sr.ReadUInt16()
@ -182,48 +153,33 @@ func (f *Font) initGlyphs(sr *d2datautils.StreamReader) error {
return err
}
var glyph FontGlyph
// two bytes of 0
glyph.unknown1, err = sr.ReadBytes(unknown1BytesCount)
if err != nil {
return err
}
sr.SkipBytes(unknown1BytesCount)
width, err := sr.ReadByte()
if err != nil {
return err
}
glyph.width = int(width)
height, err := sr.ReadByte()
if err != nil {
return err
}
glyph.height = int(height)
// 1, 0, 0
glyph.unknown2, err = sr.ReadBytes(unknown2BytesCount)
if err != nil {
return err
}
sr.SkipBytes(unknown2BytesCount)
frame, err := sr.ReadUInt16()
if err != nil {
return err
}
glyph.frame = int(frame)
// 1, 0, 0, character code repeated, and further 0.
glyph.unknown3, err = sr.ReadBytes(unknown3BytesCount)
if err != nil {
return err
}
sr.SkipBytes(unknown3BytesCount)
glyphs[rune(code)] = &glyph
glyph := d2fontglyph.Create(int(width), int(height), int(frame))
glyphs[rune(code)] = glyph
}
f.Glyphs = glyphs
@ -240,12 +196,12 @@ func (f *Font) Marshal() []byte {
for c, i := range f.Glyphs {
sw.PushUint16(uint16(c))
sw.PushBytes(i.unknown1...)
sw.PushBytes(byte(i.width))
sw.PushBytes(byte(i.height))
sw.PushBytes(i.unknown2...)
sw.PushUint16(uint16(i.frame))
sw.PushBytes(i.unknown3...)
sw.PushBytes(i.Unknown1()...)
sw.PushBytes(byte(i.Width()))
sw.PushBytes(byte(i.Height()))
sw.PushBytes(i.Unknown2()...)
sw.PushUint16(uint16(i.FrameIndex()))
sw.PushBytes(i.Unknown3()...)
}
return sw.GetBytes()