16 #include "pal_string_utils.h"
17 #include "palettizer.h"
18 #include "paletteGroup.h"
19 #include "textureImage.h"
22 #include "pnmFileTypeRegistry.h"
40 read(istream &in,
const string &filename) {
44 int ch = get_line_or_semicolon(in, line);
45 while (ch != EOF || !line.empty()) {
49 size_t hash = line.find(
'#');
50 if (hash != string::npos) {
51 line = line.substr(0, hash);
53 line = trim_left(line);
57 }
else if (line[0] ==
':') {
60 extract_words(line, words);
61 if (words[0] ==
":group") {
62 okflag = parse_group_line(words);
64 }
else if (words[0] ==
":palette") {
65 okflag = parse_palette_line(words);
67 }
else if (words[0] ==
":margin") {
68 okflag = parse_margin_line(words);
70 }
else if (words[0] ==
":background") {
71 okflag = parse_background_line(words);
73 }
else if (words[0] ==
":coverage") {
74 okflag = parse_coverage_line(words);
76 }
else if (words[0] ==
":powertwo") {
77 okflag = parse_powertwo_line(words);
79 }
else if (words[0] ==
":imagetype") {
80 okflag = parse_imagetype_line(words);
82 }
else if (words[0] ==
":shadowtype") {
83 okflag = parse_shadowtype_line(words);
85 }
else if (words[0] ==
":round") {
86 okflag = parse_round_line(words);
88 }
else if (words[0] ==
":remap") {
89 okflag = parse_remap_line(words);
91 }
else if (words[0] ==
":cutout") {
92 okflag = parse_cutout_line(words);
94 }
else if (words[0] ==
":textureswap") {
95 okflag = parse_textureswap_line(words);
98 nout <<
"Invalid keyword " << words[0] <<
"\n";
104 TxaLine &txa_line = _lines.back();
106 okflag = txa_line.
parse(line);
110 nout <<
"Error on line " << line_number <<
" of " << filename <<
"\n";
116 ch = get_line_or_semicolon(in, line);
120 nout <<
"I/O error reading " << filename <<
"\n";
138 Lines::const_iterator li;
139 for (li = _lines.begin(); li != _lines.end(); ++li) {
140 if ((*li).match_egg(egg_file)) {
159 Lines::const_iterator li;
160 for (li = _lines.begin(); li != _lines.end(); ++li) {
161 if ((*li).match_texture(texture)) {
178 Lines::const_iterator li;
179 for (li = _lines.begin(); li != _lines.end(); ++li) {
180 out << (*li) <<
"\n";
193 get_line_or_semicolon(istream &in,
string &line) {
196 char semicolon =
';';
198 while (ch != EOF && ch !=
'\n' && ch != semicolon) {
219 parse_group_line(
const vector_string &words) {
220 vector_string::const_iterator wi;
222 assert (wi != words.end());
225 const string &group_name = (*wi);
236 State state = S_none;
238 bool first_on =
true;
240 while (wi != words.end()) {
241 const string &word = (*wi);
242 if (word ==
"with") {
246 }
else if (word ==
"on") {
249 }
else if (word ==
"includes") {
252 }
else if (word ==
"dir") {
255 }
else if (word ==
"margin") {
261 nout <<
"Invalid keyword: " << word <<
"\n";
288 if (string_to_int(word, margin_override)) {
311 parse_palette_line(
const vector_string &words) {
312 if (words.size() != 3) {
313 nout <<
"Exactly two parameters required for :palette, the x and y "
314 <<
"size of the palette images to generate.\n";
318 if (!string_to_int(words[1], pal->_pal_x_size) ||
319 !string_to_int(words[2], pal->_pal_y_size)) {
320 nout <<
"Invalid palette size: " << words[1] <<
" " << words[2] <<
"\n";
324 if (pal->_pal_x_size <= 0 || pal->_pal_y_size <= 0) {
325 nout <<
"Invalid palette size: " << pal->_pal_x_size
326 <<
" " << pal->_pal_y_size <<
"\n";
341 parse_margin_line(
const vector_string &words) {
342 if (words.size() != 2) {
343 nout <<
"Exactly one parameter required for :margin, the "
344 <<
"size of the default margin to apply.\n";
348 if (!string_to_int(words[1], pal->_margin)) {
349 nout <<
"Invalid margin: " << words[1] <<
"\n";
353 if (pal->_margin < 0) {
354 nout <<
"Invalid margin: " << pal->_margin <<
"\n";
369 parse_background_line(
const vector_string &words) {
370 if (words.size() != 5) {
371 nout <<
"Exactly four parameter required for :background: the "
372 <<
"four [r g b a] components of the background color.\n";
376 if (!string_to_double(words[1], pal->_background[0]) ||
377 !string_to_double(words[2], pal->_background[1]) ||
378 !string_to_double(words[3], pal->_background[2]) ||
379 !string_to_double(words[4], pal->_background[3])) {
380 nout <<
"Invalid color: "
381 << words[1] <<
" " << words[2] <<
" "
382 << words[3] <<
" " << words[4] <<
" " <<
"\n";
397 parse_coverage_line(
const vector_string &words) {
398 if (words.size() != 2) {
399 nout <<
"Exactly one parameter required for :coverage, the "
400 <<
"value for the default coverage threshold.\n";
405 if (!string_to_double(words[1], pal->_coverage_threshold)) {
406 nout <<
"Invalid coverage threshold: " << words[1] <<
"\n";
410 if (pal->_coverage_threshold <= 0.0) {
411 nout <<
"Invalid coverage threshold: " << pal->_coverage_threshold <<
"\n";
426 parse_powertwo_line(
const vector_string &words) {
427 if (words.size() != 2) {
428 nout <<
"Exactly one parameter required for :powertwo, either a 0 "
434 if (!string_to_int(words[1], flag)) {
435 nout <<
"Invalid powertwo flag: " << words[1] <<
"\n";
439 if (flag != 0 && flag != 1) {
440 nout <<
"Invalid powertwo flag: " << flag <<
"\n";
444 pal->_force_power_2 = (flag != 0);
457 parse_imagetype_line(
const vector_string &words) {
458 if (words.size() != 2) {
459 nout <<
"Exactly one parameter required for :imagetype.\n";
462 const string &imagetype = words[1];
463 if (!parse_image_type_request(imagetype, pal->_color_type, pal->_alpha_type)) {
464 nout <<
"\nKnown image types are:\n";
482 parse_shadowtype_line(
const vector_string &words) {
483 if (words.size() != 2) {
484 nout <<
"Exactly one parameter required for :shadowtype.\n";
487 const string &shadowtype = words[1];
488 if (!parse_image_type_request(shadowtype, pal->_shadow_color_type,
489 pal->_shadow_alpha_type)) {
490 nout <<
"\nKnown image types are:\n";
507 parse_round_line(
const vector_string &words) {
508 if (words.size() == 2) {
509 if (words[1] ==
"no") {
510 pal->_round_uvs =
false;
513 nout <<
"Invalid round keyword: " << words[1] <<
".\n"
514 <<
"Expected 'no', or a round fraction and fuzz factor.\n";
519 if (words.size() != 3) {
520 nout <<
"Exactly two parameters required for :round, the fraction "
521 <<
"to round to, and the fuzz factor.\n";
525 if (!string_to_double(words[1], pal->_round_unit) ||
526 !string_to_double(words[2], pal->_round_fuzz)) {
527 nout <<
"Invalid rounding: " << words[1] <<
" " << words[2] <<
"\n";
531 if (pal->_round_unit <= 0.0 || pal->_round_fuzz < 0.0) {
532 nout <<
"Invalid rounding: " << pal->_round_unit
533 <<
" " << pal->_round_fuzz <<
"\n";
537 pal->_round_uvs =
true;
549 parse_remap_line(
const vector_string &words) {
551 while (i < (
int)words.size()) {
552 const string &keyword = words[i];
553 if (keyword ==
"char") {
556 if (i == (
int)words.size()) {
557 nout <<
"Keyword expected following 'char'\n";
561 if (pal->_remap_char_uv == Palettizer::RU_invalid) {
562 nout <<
"Invalid remap keyword: " << words[i] <<
"\n";
569 if (pal->_remap_uv == Palettizer::RU_invalid) {
570 nout <<
"Invalid remap keyword: " << words[i] <<
"\n";
574 pal->_remap_char_uv = pal->_remap_uv;
594 parse_cutout_line(
const vector_string &words) {
595 if (words.size() < 2 || words.size() > 3) {
596 nout <<
":cutout alpha-mode [ratio]\n";
601 if (am == EggRenderMode::AM_unspecified) {
602 nout <<
"Invalid cutout keyword: " << words[1] <<
"\n";
605 pal->_cutout_mode = am;
607 if (words.size() >= 3) {
608 if (!string_to_double(words[2], pal->_cutout_ratio)) {
609 nout <<
"Invalid cutout ratio: " << words[2] <<
"\n";
624 parse_textureswap_line(
const vector_string &words) {
625 vector_string::const_iterator wi;
627 assert (wi != words.end());
630 const string &group_name = (*wi);
634 string sourceTextureName = (*wi);
640 size_t dot = sourceTextureName.rfind(
'.');
641 if (dot != string::npos) {
642 sourceTextureName = sourceTextureName.substr(0, dot);
static AlphaMode string_alpha_mode(const string &string)
Returns the AlphaMode value associated with the given string representation, or AM_unspecified if the...
This is the highest level of grouping for TextureImages.
This is a single matching line in the .txa file.
void group_with(PaletteGroup *other)
Indicates a dependency of this group on some other group.
void add_texture_swap_info(const string sourceTextureName, const vector_string &swapTextures)
Store textureswap information from textures.txa.
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
static RemapUV string_remap(const string &str)
Returns the RemapUV code corresponding to the indicated string, or RU_invalid if the string is invali...
bool match_egg(EggFile *egg_file) const
Searches for a matching line in the .txa file for the given egg file and applies its specifications...
void set_dirname(const string &dirname)
Sets the directory name associated with the palette group.
const string & get_dirname() const
Returns the directory name associated with the palette group.
bool read(istream &in, const string &filename)
Reads the indicated stream, and returns true if successful, or false if there is an error...
This represents a single source texture that is referenced by one or more egg files.
void write(ostream &out) const
Outputs a representation of the lines that were read in to the indicated output stream.
bool parse(const string &line)
Accepts a string that defines a line of the .txa file and parses it into its constinuent parts...
PaletteGroup * get_palette_group(const string &name)
Returns the PaletteGroup with the given name.
bool has_dirname() const
Returns true if the directory name has been explicitly set for this group.
This represents a single egg file known to the palettizer.
void write(ostream &out, int indent_level=0) const
Writes a list of supported image file types to the indicated output stream, one per line...
void set_margin_override(const int override)
Returns the set of groups this group depends on.
bool match_texture(TextureImage *texture) const
Searches for a matching line in the .txa file for the given texture and applies its specifications...