1 /*****************************************************************************/
3 // Written by Michael Wilber, OBOS Translation Kit Team
7 // stxtinfo is a command line program for displaying text information about
8 // Be styled text (the format that StyledEdit uses). StyledEdit stores the
9 // styled text information as an attribute of the file and it is this
10 // information that this program is concerned with. This format is outlined
11 // in TranslatorFormats.h.
13 // This program prints out information from the "styles" attribute that
14 // StyledEdit uses. If that information is not available, it attempts
15 // to read the styles information from the contents of the file, assuming
16 // that it is the format that BTranslationUtils::PutStyledText() writes
19 // The intention of this program is to aid with the development and
20 // debugging of the STXTTranslator. It may also be useful for debugging /
21 // testing StyledEdit.
23 // This application and all source files used in its construction, except
24 // where noted, are licensed under the MIT License, and have been written
27 // Copyright (c) 2003 OpenBeOS Project
29 // Permission is hereby granted, free of charge, to any person obtaining a
30 // copy of this software and associated documentation files (the "Software"),
31 // to deal in the Software without restriction, including without limitation
32 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
33 // and/or sell copies of the Software, and to permit persons to whom the
34 // Software is furnished to do so, subject to the following conditions:
36 // The above copyright notice and this permission notice shall be included
37 // in all copies or substantial portions of the Software.
39 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
40 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
42 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
44 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
45 // DEALINGS IN THE SOFTWARE.
46 /*****************************************************************************/
50 #include <ByteOrder.h>
52 #include <TranslatorFormats.h>
58 #define max(x,y) ((x > y) ? x : y)
59 #define DATA_BUFFER_SIZE 64
62 uint32 magic
; // 41 6c 69 21
72 float shear
; // typically 90.0
73 uint16 face
; // typically 0
77 uint8 alpha
; // 255 == opaque
82 PrintStyle(Style
&style
, int32 i
)
84 style
.offset
= B_BENDIAN_TO_HOST_INT32(style
.offset
);
85 style
.size
= B_BENDIAN_TO_HOST_FLOAT(style
.size
);
86 style
.shear
= B_BENDIAN_TO_HOST_FLOAT(style
.shear
);
87 style
.face
= B_BENDIAN_TO_HOST_INT16(style
.face
);
88 style
.reserved
= B_BENDIAN_TO_HOST_INT16(style
.reserved
);
90 printf("\nStyle %d:\n", static_cast<int>(i
+ 1));
91 printf("offset: %d\n", static_cast<int>(style
.offset
));
92 printf("family: %s\n", style
.family
);
93 printf("style: %s\n", style
.style
);
94 printf("size: %f\n", style
.size
);
95 printf("shear: %f (typically 90.0)\n", style
.shear
);
96 printf("face: %u (typically 0)\n",
97 static_cast<unsigned int>(style
.face
));
98 printf("RGBA: (%u, %u, %u, %u)\n",
99 static_cast<unsigned int>(style
.red
),
100 static_cast<unsigned int>(style
.blue
),
101 static_cast<unsigned int>(style
.green
),
102 static_cast<unsigned int>(style
.alpha
));
103 printf("reserved: %u (should be 0)\n",
104 static_cast<unsigned int>(style
.reserved
));
108 PrintStylesAttribute(BFile
&file
)
110 const char *kAttrName
= "styles";
113 if (file
.GetAttrInfo(kAttrName
, &info
) != B_OK
)
115 if (info
.type
!= B_RAW_TYPE
) {
116 printf("Error: styles attribute is of the wrong type\n");
119 if (info
.size
< 160) {
120 printf("Error: styles attribute is missing information\n");
124 uint8
*pflatRunArray
= new uint8
[info
.size
];
125 if (!pflatRunArray
) {
126 printf("Error: Not enough memory available to read styles attribute\n");
130 ssize_t amtread
= file
.ReadAttr(kAttrName
, B_RAW_TYPE
, 0,
131 pflatRunArray
, info
.size
);
132 if (amtread
!= info
.size
) {
133 printf("Error: Unable to read styles attribute\n");
138 StylesHeader stylesheader
;
139 memcpy(&stylesheader
, pflatRunArray
, sizeof(StylesHeader
));
140 if (swap_data(B_UINT32_TYPE
, &stylesheader
, sizeof(StylesHeader
),
141 B_SWAP_BENDIAN_TO_HOST
) != B_OK
) {
142 printf("Error: Unable to swap byte order of styles header\n");
146 // Print StylesHeader info
147 printf("\"styles\" attribute data:\n\n");
149 printf("magic number: 0x%.8lx ",
150 static_cast<unsigned long>(stylesheader
.magic
));
151 if (stylesheader
.magic
== 'Ali!')
154 printf("(INVALID, should be 0x%.8lx)\n",
155 static_cast<unsigned long>('Ali!'));
157 printf("version: 0x%.8lx ",
158 static_cast<unsigned long>(stylesheader
.version
));
159 if (stylesheader
.version
== 0)
162 printf("(INVALID, should be 0x%.8lx)\n", 0UL);
164 printf("number of styles: %d\n",
165 static_cast<int>(stylesheader
.count
));
167 // Check and Print out each style
168 Style
*pstyle
= reinterpret_cast<Style
*>(pflatRunArray
+ sizeof(StylesHeader
));
169 for (int32 i
= 0; i
< stylesheader
.count
; i
++)
170 PrintStyle(*(pstyle
+ i
), i
);
172 delete[] pflatRunArray
;
173 pflatRunArray
= NULL
;
179 PrintStxtInfo(BFile
&file
)
181 const uint32 kstxtsize
= sizeof(TranslatorStyledTextStreamHeader
);
182 const uint32 ktxtsize
= sizeof(TranslatorStyledTextTextHeader
);
183 const uint32 kstylsize
= sizeof(TranslatorStyledTextStyleHeader
);
184 const uint32 kStyleSize
= sizeof(Style
);
186 uint8 buffer
[max(max(max(kstxtsize
, ktxtsize
), kstylsize
), kStyleSize
)];
190 nread
= file
.Read(buffer
, kstxtsize
);
191 if (nread
!= static_cast<status_t
>(kstxtsize
)) {
192 printf("Error: Unable to read stream header\n");
195 TranslatorStyledTextStreamHeader stxtheader
;
196 memcpy(&stxtheader
, buffer
, kstxtsize
);
197 if (swap_data(B_UINT32_TYPE
, &stxtheader
, kstxtsize
,
198 B_SWAP_BENDIAN_TO_HOST
) != B_OK
) {
199 printf("Error: Unable to swap byte order of stream header\n");
203 if (stxtheader
.header
.magic
!= B_STYLED_TEXT_FORMAT
) {
204 printf("Styled text magic number is incorrect, aborting.\n");
208 // Print Stream Header (STXT)
209 printf("Stream Header (STXT section):\n\n");
211 printf("magic number: 0x%.8lx ", stxtheader
.header
.magic
);
212 if (stxtheader
.header
.magic
== B_STYLED_TEXT_FORMAT
)
215 printf("(INVALID, should be 0x%.8lx)\n",
216 static_cast<unsigned long>(B_STYLED_TEXT_FORMAT
));
218 printf("header size: %u ",
219 static_cast<unsigned int>(stxtheader
.header
.header_size
));
220 if (stxtheader
.header
.header_size
== kstxtsize
)
223 printf("(INVALID, should be %u)\n",
224 static_cast<unsigned int>(kstxtsize
));
226 printf("data size: %u ",
227 static_cast<unsigned int>(stxtheader
.header
.data_size
));
228 if (stxtheader
.header
.data_size
== 0)
231 printf("(INVALID, should be 0)\n");
233 printf("version: %d ",
234 static_cast<int>(stxtheader
.version
));
235 if (stxtheader
.version
== 100)
238 printf("(INVALID, should be 100)\n");
241 // Check the TEXT header
242 TranslatorStyledTextTextHeader txtheader
;
243 if (file
.Read(buffer
, ktxtsize
) != static_cast<ssize_t
>(ktxtsize
)) {
244 printf("Error: Unable to read text header\n");
247 memcpy(&txtheader
, buffer
, ktxtsize
);
248 if (swap_data(B_UINT32_TYPE
, &txtheader
, ktxtsize
,
249 B_SWAP_BENDIAN_TO_HOST
) != B_OK
) {
250 printf("Error: Unable to swap byte order of text header\n");
254 // Print Text Header (TEXT)
255 printf("\nText Header (TEXT section):\n\n");
257 printf("magic number: 0x%.8lx ", txtheader
.header
.magic
);
258 if (txtheader
.header
.magic
== 'TEXT')
261 printf("(INVALID, should be 0x%.8lx)\n",
262 static_cast<unsigned long>('TEXT'));
264 printf("header size: %u ",
265 static_cast<unsigned int>(txtheader
.header
.header_size
));
266 if (stxtheader
.header
.header_size
== ktxtsize
)
269 printf("(INVALID, should be %u)\n",
270 static_cast<unsigned int>(ktxtsize
));
272 printf("data size (bytes of text): %u\n",
273 static_cast<unsigned int>(txtheader
.header
.data_size
));
275 printf("character set: %d ",
276 static_cast<int>(txtheader
.charset
));
277 if (txtheader
.charset
== B_UNICODE_UTF8
)
280 printf("(INVALID, should be %d)\n", B_UNICODE_UTF8
);
282 // Skip the text data
283 off_t seekresult
, pos
;
284 pos
= stxtheader
.header
.header_size
+
285 txtheader
.header
.header_size
+
286 txtheader
.header
.data_size
;
287 seekresult
= file
.Seek(txtheader
.header
.data_size
, SEEK_CUR
);
288 if (seekresult
< pos
) {
289 printf("Error: Unable to seek past text data. " \
290 "Text data could be missing\n");
293 if (seekresult
> pos
) {
294 printf("Error: File position is beyond expected value\n");
298 // Check the STYL header (not all STXT files have this)
300 TranslatorStyledTextStyleHeader stylheader
;
301 read
= file
.Read(buffer
, kstylsize
);
302 if (read
!= static_cast<ssize_t
>(kstylsize
) && read
!= 0) {
303 printf("Error: Unable to read entire style header\n");
307 // If there is no STYL header (and no errors)
308 if (read
!= static_cast<ssize_t
>(kstylsize
)) {
309 printf("\nFile contains no Style Header (STYL section)\n");
313 memcpy(&stylheader
, buffer
, kstylsize
);
314 if (swap_data(B_UINT32_TYPE
, &stylheader
, kstylsize
,
315 B_SWAP_BENDIAN_TO_HOST
) != B_OK
) {
316 printf("Error: Unable to swap byte order of style header\n");
320 // Print Style Header (STYL)
321 printf("\nStyle Header (STYL section):\n\n");
323 printf("magic number: 0x%.8lx ", stylheader
.header
.magic
);
324 if (stylheader
.header
.magic
== 'STYL')
327 printf("(INVALID, should be 0x%.8lx)\n",
328 static_cast<unsigned long>('STYL'));
330 printf("header size: %u ",
331 static_cast<unsigned int>(stylheader
.header
.header_size
));
332 if (stylheader
.header
.header_size
== kstylsize
)
335 printf("(INVALID, should be %u)\n",
336 static_cast<unsigned int>(kstylsize
));
338 printf("data size: %u\n",
339 static_cast<unsigned int>(stylheader
.header
.data_size
));
340 printf("apply offset: %u (usually 0)\n",
341 static_cast<unsigned int>(stylheader
.apply_offset
));
342 printf("apply length: %u (usually the text data size)\n",
343 static_cast<unsigned int>(stylheader
.apply_length
));
346 StylesHeader stylesheader
;
347 read
= file
.Read(buffer
, sizeof(StylesHeader
));
348 if (read
!= sizeof(StylesHeader
)) {
349 printf("Error: Unable to read Styles header\n");
352 memcpy(&stylesheader
, buffer
, sizeof(StylesHeader
));
353 if (swap_data(B_UINT32_TYPE
, &stylesheader
, sizeof(StylesHeader
),
354 B_SWAP_BENDIAN_TO_HOST
) != B_OK
) {
355 printf("Error: Unable to swap byte order of styles header\n");
359 // Print StylesHeader info
360 printf("\nStyles Header (Ali! section):\n\n");
362 printf("magic number: 0x%.8lx ",
363 static_cast<unsigned long>(stylesheader
.magic
));
364 if (stylesheader
.magic
== 'Ali!')
367 printf("(INVALID, should be 0x%.8lx)\n",
368 static_cast<unsigned long>('Ali!'));
370 printf("version: 0x%.8lx ",
371 static_cast<unsigned long>(stylesheader
.version
));
372 if (stylesheader
.version
== 0)
375 printf("(INVALID, should be 0x%.8lx)\n", 0UL);
377 printf("number of styles: %d\n",
378 static_cast<int>(stylesheader
.count
));
380 // Check and Print out each style
381 for (int32 i
= 0; i
< stylesheader
.count
; i
++) {
383 read
= file
.Read(&style
, sizeof(Style
));
384 if (read
!= sizeof(Style
)) {
385 printf("Error: Unable to read style %d\n",
386 static_cast<int>(i
+ 1));
390 PrintStyle(style
, i
);
397 main(int argc
, char **argv
)
402 BFile
file(argv
[1], B_READ_ONLY
);
403 if (file
.InitCheck() != B_OK
)
404 printf("Error opening %s\n", argv
[1]);
406 printf("Be styled text information for: %s\n\n", argv
[1]);
407 if (PrintStylesAttribute(file
) == false) {
408 printf("Unable to read styles attribute, attempting to read " \
409 "style information from file...\n\n");
415 printf("stxtinfo - reports information about a Be styled text file\n");
416 printf("\nUsage:\n");
417 printf("stxtinfo filename.stxt\n");