Skip to content

Commit da21344

Browse files
committed
支持编码格式内容
1 parent 232d5bd commit da21344

4 files changed

Lines changed: 139 additions & 94 deletions

File tree

Workbench/Wmf/SkiaWmfRenderer/src/wieslawsoltes-wmf/src/library/Records/Drawing/WmfExtTextoutRecord.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public UInt16[]? Dx
8181
public string GetText(Encoding encoding)
8282
{
8383
var text = encoding.GetString(TextByteArray);
84-
if (Dx != null && Dx.Length!=text.Length)
84+
if (Dx != null && Dx.Length != text.Length)
8585
{
8686
throw new WmfException($"Dx length mush equals text length.");
8787
}
Lines changed: 110 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,115 @@
1-
using System.IO;
1+
using Oxage.Wmf.Extensions;
2+
3+
using System.IO;
4+
using System.Linq;
25
using System.Text;
36

47
namespace Oxage.Wmf.Records
58
{
6-
[WmfRecord(Type = RecordType.META_TEXTOUT, SizeIsVariable = true)]
7-
public class WmfTextoutRecord : WmfBinaryRecord
8-
{
9-
public WmfTextoutRecord() : base()
10-
{
11-
}
12-
13-
public short StringLength
14-
{
15-
get;
16-
set;
17-
}
18-
19-
public string StringValue
20-
{
21-
get;
22-
set;
23-
}
24-
25-
public short YStart
26-
{
27-
get;
28-
set;
29-
}
30-
31-
public short XStart
32-
{
33-
get;
34-
set;
35-
}
36-
37-
protected Encoding StringEncoding
38-
{
39-
get
40-
{
41-
return WmfHelper.GetAnsiEncoding();
42-
}
43-
}
44-
45-
public override void Read(BinaryReader reader)
46-
{
47-
this.StringLength = reader.ReadInt16();
48-
49-
if (this.StringLength > 0)
50-
{
51-
byte[] ansi = reader.ReadBytes(this.StringLength);
52-
this.StringValue = StringEncoding.GetString(ansi);
53-
}
54-
55-
this.YStart = reader.ReadInt16();
56-
this.XStart = reader.ReadInt16();
57-
}
58-
59-
public override void Write(BinaryWriter writer)
60-
{
61-
byte[] ansi = StringEncoding.GetBytes(this.StringValue ?? "");
62-
int offset = (ansi.Length % 2 == 1 ? +1 : +0); //1 extra byte for odd-length string
63-
64-
base.RecordSizeBytes = (uint)(6 /* RecordSize and RecordFunction */ + 2 + (ansi.Length + offset) + 2 + 2 /* Parameters */);
65-
base.Write(writer);
66-
67-
writer.Write(this.StringLength > 0 ? this.StringLength : (short)(ansi.Length + offset));
68-
writer.Write(ansi);
69-
70-
if (ansi.Length % 2 == 1)
71-
{
72-
//Write a dummy byte after odd-length string so the record aligns to 16-bit boundary
73-
writer.Write((byte)0x00);
74-
}
75-
76-
writer.Write(this.YStart);
77-
writer.Write(this.XStart);
78-
}
79-
80-
protected override void Dump(StringBuilder builder)
81-
{
82-
base.Dump(builder);
83-
builder.AppendLine("StringLength: " + this.StringLength);
84-
builder.AppendLine("String: " + this.StringValue);
85-
builder.AppendLine("YStart: " + this.YStart);
86-
builder.AppendLine("XStart: " + this.XStart);
87-
}
88-
}
9+
[WmfRecord(Type = RecordType.META_TEXTOUT, SizeIsVariable = true)]
10+
public class WmfTextoutRecord : WmfBinaryRecord
11+
{
12+
public WmfTextoutRecord() : base()
13+
{
14+
}
15+
16+
public short StringLength
17+
{
18+
get;
19+
set;
20+
}
21+
22+
public string GetText(Encoding encoding)
23+
{
24+
var text = encoding.GetString(TextByteArray);
25+
return text;
26+
}
27+
28+
public string GetText(CharacterSet characterSet) => GetText(characterSet.ToEncoding());
29+
30+
public byte[] TextByteArray
31+
{
32+
get => _textByteArray;
33+
set
34+
{
35+
_textByteArray = value;
36+
StringLength = (short) value.Length;
37+
}
38+
}
39+
40+
private byte[] _textByteArray;
41+
42+
43+
public short YStart
44+
{
45+
get;
46+
set;
47+
}
48+
49+
public short XStart
50+
{
51+
get;
52+
set;
53+
}
54+
55+
protected Encoding StringEncoding
56+
{
57+
get
58+
{
59+
return WmfHelper.GetAnsiEncoding();
60+
}
61+
}
62+
63+
public override void Read(BinaryReader reader)
64+
{
65+
this.StringLength = reader.ReadInt16();
66+
67+
if (this.StringLength > 0)
68+
{
69+
byte[] textByteArray = reader.ReadBytes(this.StringLength);
70+
TextByteArray = textByteArray;
71+
}
72+
73+
// String (variable): The size of this field MUST be a multiple of two. If StringLength is an odd number, then this field MUST be of a size greater than or equal to StringLength + 1. A variable-length string that specifies the text to be drawn. The string does not need to be null-terminated, because StringLength specifies the length of the string. The string is written at the location specified by the XStart and YStart fields. See section 2.3.3.5 for information about the encoding of the field.
74+
var isOdd = StringLength % 2 == 1;
75+
if (isOdd)
76+
{
77+
reader.ReadByte();
78+
}
79+
80+
this.YStart = reader.ReadInt16();
81+
this.XStart = reader.ReadInt16();
82+
}
83+
84+
public override void Write(BinaryWriter writer)
85+
{
86+
byte[] textByteArray = TextByteArray;
87+
int offset = (textByteArray.Length % 2 == 1 ? +1 : +0); //1 extra byte for odd-length string
88+
89+
base.RecordSizeBytes = (uint) (6 /* RecordSize and RecordFunction */ + 2 + (textByteArray.Length + offset) + 2 + 2 /* Parameters */);
90+
base.Write(writer);
91+
92+
writer.Write(this.StringLength > 0 ? this.StringLength : (short) (textByteArray.Length + offset));
93+
writer.Write(textByteArray);
94+
95+
if (textByteArray.Length % 2 == 1)
96+
{
97+
//Write a dummy byte after odd-length string so the record aligns to 16-bit boundary
98+
writer.Write((byte) 0x00);
99+
}
100+
101+
writer.Write(this.YStart);
102+
writer.Write(this.XStart);
103+
}
104+
105+
protected override void Dump(StringBuilder builder)
106+
{
107+
base.Dump(builder);
108+
builder.AppendLine("StringLength: " + this.StringLength);
109+
builder.AppendLine("TextByteArray: " + string.Join(',', TextByteArray.Select(t => t.ToString("X2"))));
110+
builder.AppendLine("GuessText:" + WmfHelper.GetAnsiEncoding().GetString(TextByteArray));
111+
builder.AppendLine("YStart: " + this.YStart);
112+
builder.AppendLine("XStart: " + this.XStart);
113+
}
114+
}
89115
}

Workbench/Wmf/SkiaWmfRenderer/src/wieslawsoltes-wmf/src/library/WmfDocument.cs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.IO;
33
using System.Linq;
44
using System.Text;
5+
using Oxage.Wmf.Extensions;
56
using Oxage.Wmf.Primitive;
67
using Oxage.Wmf.Records;
78

@@ -309,12 +310,13 @@ public WmfEllipseRecord AddEllipse(Point center, Point radius)
309310
return record;
310311
}
311312

312-
/// <summary>
313-
/// Add a circle (equi-radius ellipse) by specifying its center and radius
314-
/// </summary>
315-
/// <param name="center"></param>
316-
/// <param name="radius"></param>
317-
public WmfEllipseRecord AddCircle(int x, int y, int radius)
313+
/// <summary>
314+
/// Add a circle (equi-radius ellipse) by specifying its center and radius
315+
/// </summary>
316+
/// <param name="x">Center X</param>
317+
/// <param name="y">Center Y</param>
318+
/// <param name="radius"></param>
319+
public WmfEllipseRecord AddCircle(int x, int y, int radius)
318320
{
319321
return AddEllipse(new Point(x, y), new Point(radius, radius));
320322
}
@@ -407,9 +409,22 @@ public WmfSetTextColorRecord AddTextColor(Color color)
407409

408410
public WmfTextoutRecord AddText(string text, int x = 0, int y = 0)
409411
{
410-
var record = new WmfTextoutRecord()
412+
byte[] textByteArray;
413+
if(string.IsNullOrEmpty(text))
414+
{
415+
textByteArray = [];
416+
}
417+
else
418+
{
419+
// Find the encoding form CharacterSet in Records
420+
var lastWmfCreateFontIndirectRecord = Records.OfType<WmfCreateFontIndirectRecord>().LastOrDefault();
421+
var encoding = lastWmfCreateFontIndirectRecord?.CharSet.ToEncoding() ?? WmfHelper.GetAnsiEncoding();
422+
textByteArray = encoding.GetBytes(text);
423+
}
424+
425+
var record = new WmfTextoutRecord()
411426
{
412-
StringValue = text,
427+
TextByteArray = textByteArray,
413428
XStart = (short)x,
414429
YStart = (short)y
415430
};

Workbench/Wmf/SkiaWmfRenderer/src/wieslawsoltes-wmf/src/library/WmfHelper.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ private static Dictionary<RecordType, RecordCreator> RecordCreatorDictionary
4646

4747
readonly record struct RecordCreator(Type Type, WmfRecordAttribute Attribute, Func<IBinaryRecord> Creator);
4848

49+
/// <summary>
50+
/// This method is used to export all binary records that are defined in the library. PowerBy Telescope, the source generator.
51+
/// </summary>
52+
/// <returns></returns>
4953
[dotnetCampus.Telescope.TelescopeExportAttribute()]
5054
private static partial IEnumerable<(Type type, WmfRecordAttribute attribute, Func<IBinaryRecord> creator)> ExportBinaryRecordEnumerable();
5155

@@ -115,7 +119,7 @@ public static WmfDocument GetExampleFromSpecificationDocument()
115119
wmf.Records.Add(new WmfTextoutRecord()
116120
{
117121
StringLength = 0x000C,
118-
StringValue = "Hello People",
122+
TextByteArray = WmfHelper.GetAnsiEncoding().GetBytes("Hello People"),
119123
YStart = 0x000A,
120124
XStart = 0x000A
121125
});

0 commit comments

Comments
 (0)