mirror of
https://github.com/ganelson/inform.git
synced 2024-07-16 22:14:23 +03:00
447 lines
15 KiB
OpenEdge ABL
447 lines
15 KiB
OpenEdge ABL
[FiguresElement::] Figures Element.
|
|
|
|
To write the Figures element (Fi) in the index.
|
|
|
|
@ Not only figures but also sounds and external files, a little questionably.
|
|
|
|
=
|
|
void FiguresElement::render(OUTPUT_STREAM, index_session *session) {
|
|
localisation_dictionary *LD = Indexing::get_localisation(session);
|
|
inter_tree *I = Indexing::get_tree(session);
|
|
tree_inventory *inv = Indexing::get_inventory(session);
|
|
InterNodeList::array_sort(inv->figure_nodes, MakeSynopticModuleStage::module_order);
|
|
InterNodeList::array_sort(inv->sound_nodes, MakeSynopticModuleStage::module_order);
|
|
InterNodeList::array_sort(inv->file_nodes, MakeSynopticModuleStage::module_order);
|
|
@<Index the figures@>;
|
|
@<Index the sounds@>;
|
|
@<Index the internal files@>;
|
|
@<Index the files@>;
|
|
}
|
|
|
|
@h Figures.
|
|
|
|
@<Index the figures@> =
|
|
if (InterNodeList::array_len(inv->figure_nodes) <= 1) { /* cover art always creates 1 */
|
|
HTML_OPEN("p");
|
|
Localisation::roman(OUT, LD, I"Index.Elements.Fi.NoFigures");
|
|
HTML_CLOSE("p");
|
|
} else {
|
|
HTML_OPEN("p");
|
|
Localisation::bold(OUT, LD, I"Index.Elements.Fi.ListOfFigures");
|
|
HTML_CLOSE("p");
|
|
@<Tabulate the figures@>;
|
|
}
|
|
|
|
@ The table is presented with thumbnails of a given pixel width, which
|
|
the HTML renderer automatically scales to fit. Height is adjusted so as
|
|
to match this width, preserving the aspect ratio.
|
|
|
|
@d THUMBNAIL_WIDTH 80
|
|
|
|
=
|
|
@<Tabulate the figures@> =
|
|
inter_package *settings = InterPackage::from_URL(I, I"/main/completion/basics");
|
|
int MAX_INDEXED_FIGURES =
|
|
(int) Metadata::read_optional_numeric(settings, I"^max_indexed_figures");
|
|
HTML::begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
|
|
int count_of_displayed_figures = 0;
|
|
inter_package *pack;
|
|
LOOP_OVER_INVENTORY_PACKAGES(pack, i, inv->figure_nodes) {
|
|
inter_ti id = Metadata::read_numeric(pack, I"^resource_id");
|
|
if (id > 1) {
|
|
text_stream *filename_as_text = Metadata::required_textual(pack, I"^filename");
|
|
filename *F = Filenames::from_text(filename_as_text);
|
|
TEMPORARY_TEXT(description)
|
|
unsigned int width = 0, height = 0;
|
|
int format_found = 0;
|
|
@<Find image format and dimensions@>;
|
|
@<Render a table row for the image@>;
|
|
DISCARD_TEXT(description)
|
|
}
|
|
}
|
|
HTML::end_html_table(OUT);
|
|
if (count_of_displayed_figures > MAX_INDEXED_FIGURES) {
|
|
HTML_OPEN("p");
|
|
WRITE("(");
|
|
Localisation::roman_ii(OUT, LD, I"Index.Elements.Fi.ThumbnailLimit",
|
|
MAX_INDEXED_FIGURES, 10*MAX_INDEXED_FIGURES);
|
|
WRITE(")");
|
|
HTML_CLOSE("p");
|
|
}
|
|
|
|
@<Find image format and dimensions@> =
|
|
FILE *FIGURE_FILE = Filenames::fopen(F, "rb");
|
|
if (FIGURE_FILE) {
|
|
text_stream *real_format = I"JPEG";
|
|
format_found = ImageFiles::get_JPEG_dimensions(FIGURE_FILE, &width, &height);
|
|
fclose(FIGURE_FILE);
|
|
if (format_found == 0) {
|
|
FIGURE_FILE = Filenames::fopen(F, "rb");
|
|
if (FIGURE_FILE) {
|
|
real_format = I"PNG";
|
|
format_found = ImageFiles::get_PNG_dimensions(FIGURE_FILE, &width, &height);
|
|
fclose(FIGURE_FILE);
|
|
}
|
|
}
|
|
if (format_found == 0) {
|
|
Localisation::italic(description, LD, I"Index.Elements.Fi.UnknownFormat");
|
|
} else {
|
|
Localisation::roman_t(description, LD, I"Index.Elements.Fi.Format", real_format);
|
|
WRITE_TO(description, ": ");
|
|
Localisation::roman_ii(description, LD, I"Index.Elements.Fi.Dimensions",
|
|
(int) width, (int) height);
|
|
}
|
|
} else {
|
|
Localisation::italic(description, LD, I"Index.Elements.Fi.Missing");
|
|
}
|
|
|
|
@<Render a table row for the image@> =
|
|
HTML::first_html_column(OUT, THUMBNAIL_WIDTH+10);
|
|
if (format_found == 0) {
|
|
HTML_TAG_WITH("img",
|
|
"border=\"0\" src=\"inform:/doc_images/image_problem.png\"");
|
|
WRITE(" ");
|
|
} else if (count_of_displayed_figures++ < MAX_INDEXED_FIGURES) {
|
|
HTML_TAG_WITH("img",
|
|
"border=\"1\" src=\"file://%f\" width=\"%d\" height=\"%d\"",
|
|
F, THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*height/width);
|
|
WRITE(" ");
|
|
} else {
|
|
HTML_OPEN_WITH("div",
|
|
"class=\"figureindexbox\" style=\"width:%dpx; height:%dpx; border:1px solid;\"",
|
|
THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*height/width);
|
|
WRITE(" ");
|
|
HTML_CLOSE("div");
|
|
}
|
|
|
|
HTML::next_html_column(OUT, 0);
|
|
WRITE("%S", Metadata::required_textual(pack, I"^name"));
|
|
IndexUtilities::link_package(OUT, pack);
|
|
HTML_TAG("br");
|
|
if (Str::len(description) > 0) {
|
|
WRITE("%S", description);
|
|
HTML_TAG("br");
|
|
}
|
|
Localisation::roman_ti(description, LD, I"Index.Elements.Fi.Resource",
|
|
Filenames::get_leafname(F), (int) id);
|
|
HTML::end_html_row(OUT);
|
|
|
|
@h Sounds.
|
|
|
|
@<Index the sounds@> =
|
|
HTML_OPEN("p");
|
|
Localisation::bold(OUT, LD, I"Index.Elements.Fi.ListOfSounds");
|
|
HTML_CLOSE("p");
|
|
if (InterNodeList::array_len(inv->sound_nodes) == 0) {
|
|
HTML_OPEN("p");
|
|
Localisation::roman(OUT, LD, I"Index.Elements.Fi.NoSounds");
|
|
HTML_CLOSE("p");
|
|
} else {
|
|
@<Tabulate the sounds@>;
|
|
}
|
|
|
|
@<Tabulate the sounds@> =
|
|
HTML::begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
|
|
inter_package *pack;
|
|
LOOP_OVER_INVENTORY_PACKAGES(pack, i, inv->sound_nodes) {
|
|
inter_ti id = Metadata::read_numeric(pack, I"^resource_id");
|
|
text_stream *filename_as_text = Metadata::required_textual(pack, I"^filename");
|
|
filename *F = Filenames::from_text(filename_as_text);
|
|
unsigned int duration, pBitsPerSecond, pChannels, pSampleRate, fsize,
|
|
midi_version = 0, no_tracks = 0;
|
|
int preview = TRUE, waveform_style = TRUE;
|
|
TEMPORARY_TEXT(description)
|
|
int format_found = 0;
|
|
@<Find sound format and duration@>
|
|
@<Render a table row for the sound@>;
|
|
DISCARD_TEXT(description)
|
|
}
|
|
HTML::end_html_table(OUT);
|
|
|
|
@<Find sound format and duration@> =
|
|
FILE *SOUND_FILE = Filenames::fopen(F, "rb");
|
|
if (SOUND_FILE) {
|
|
text_stream *real_format = I"AIFF";
|
|
format_found = SoundFiles::get_AIFF_duration(SOUND_FILE, &duration, &pBitsPerSecond,
|
|
&pChannels, &pSampleRate);
|
|
fseek(SOUND_FILE, 0, SEEK_END);
|
|
fsize = (unsigned int) (ftell(SOUND_FILE));
|
|
fclose(SOUND_FILE);
|
|
if (format_found == 0) {
|
|
SOUND_FILE = Filenames::fopen(F, "rb");
|
|
if (SOUND_FILE) {
|
|
real_format = I"Ogg Vorbis";
|
|
preview = FALSE;
|
|
format_found = SoundFiles::get_OggVorbis_duration(SOUND_FILE, &duration,
|
|
&pBitsPerSecond, &pChannels, &pSampleRate);
|
|
fclose(SOUND_FILE);
|
|
}
|
|
}
|
|
if (format_found == 0) {
|
|
SOUND_FILE = Filenames::fopen(F, "rb");
|
|
if (SOUND_FILE) {
|
|
waveform_style = FALSE;
|
|
real_format = I"MIDI";
|
|
preview = TRUE;
|
|
format_found = SoundFiles::get_MIDI_information(SOUND_FILE,
|
|
&midi_version, &no_tracks);
|
|
fclose(SOUND_FILE);
|
|
}
|
|
}
|
|
if (format_found == 0) {
|
|
Localisation::italic(description, LD, I"Index.Elements.Fi.UnknownSoundFormat");
|
|
} else {
|
|
if (waveform_style == FALSE) @<Describe sound in MIDI format@>
|
|
else @<Describe sound in waveform format@>;
|
|
}
|
|
} else {
|
|
Localisation::italic(description, LD, I"Index.Elements.Fi.MissingSound");
|
|
}
|
|
|
|
@<Describe sound in MIDI format@> =
|
|
if (no_tracks == 1) {
|
|
Localisation::roman_it(description, LD, I"Index.Elements.Fi.SoundFormatOneTrack",
|
|
(int) midi_version, real_format);
|
|
} else {
|
|
Localisation::write_iti(description, LD, I"Index.Elements.Fi.SoundFormatMultiTrack",
|
|
(int) midi_version, real_format, (int) no_tracks);
|
|
}
|
|
WRITE_TO(description, " - ");
|
|
Localisation::italic(description, LD, I"Index.Elements.Fi.SoundUnsupported");
|
|
|
|
@<Describe sound in waveform format@> =
|
|
TEMPORARY_TEXT(size)
|
|
WRITE_TO(size, "%d.%01dKB", fsize/1024, (fsize%1024)/102);
|
|
Localisation::roman_tt(description, LD, I"Index.Elements.Fi.SoundFile", size, real_format);
|
|
DISCARD_TEXT(size)
|
|
int min = (duration/6000), sec = (duration%6000)/100, centisec = (duration%100);
|
|
WRITE_TO(description, ": ");
|
|
TEMPORARY_TEXT(seconds)
|
|
if (centisec == 0) WRITE_TO(seconds, "%d", sec);
|
|
else WRITE_TO(seconds, "%d.%02d", sec, centisec);
|
|
if (min > 0) {
|
|
if ((sec > 0) || (centisec > 0)) {
|
|
Localisation::roman_it(description, LD, I"Index.Elements.Fi.DurationMS",
|
|
min, seconds);
|
|
} else {
|
|
Localisation::roman_i(description, LD, I"Index.Elements.Fi.DurationM", min);
|
|
}
|
|
} else {
|
|
Localisation::roman_t(description, LD, I"Index.Elements.Fi.DurationS", seconds);
|
|
}
|
|
DISCARD_TEXT(seconds)
|
|
WRITE_TO(description, "<br>");
|
|
TEMPORARY_TEXT(sample)
|
|
WRITE_TO(sample, "%d.%01dkHz", pSampleRate/1000, (pSampleRate%1000)/100);
|
|
Localisation::roman_t(description, LD, I"Index.Elements.Fi.Sampled", sample);
|
|
DISCARD_TEXT(sample)
|
|
WRITE_TO(description, " ");
|
|
if (pChannels == 1) Localisation::roman(OUT, LD, I"Index.Elements.Fi.Mono");
|
|
else Localisation::roman(description, LD, I"Index.Elements.Fi.Stereo");
|
|
WRITE_TO(description, " (");
|
|
TEMPORARY_TEXT(bitrate)
|
|
WRITE_TO(bitrate, "%d.%01d", pBitsPerSecond/1000, (pSampleRate%1000)/100);
|
|
Localisation::roman_t(description, LD, I"Index.Elements.Fi.BitRate", bitrate);
|
|
DISCARD_TEXT(bitrate)
|
|
WRITE_TO(description, ")");
|
|
|
|
@<Render a table row for the sound@> =
|
|
HTML::first_html_column(OUT, THUMBNAIL_WIDTH+10);
|
|
if (format_found == 0) {
|
|
HTML_TAG_WITH("img", "border=\"0\" src=\"inform:/doc_images/image_problem.png\"");
|
|
} else if (preview) {
|
|
HTML_OPEN_WITH("embed",
|
|
"src=\"file://%f\" width=\"%d\" height=\"64\" "
|
|
"autostart=\"false\" volume=\"50%%\" mastersound",
|
|
F, THUMBNAIL_WIDTH);
|
|
HTML_CLOSE("embed");
|
|
} else {
|
|
HTML_TAG_WITH("img", "border=\"0\" src=\"inform:/doc_images/sound_okay.png\"");
|
|
}
|
|
WRITE(" ");
|
|
HTML::next_html_column(OUT, 0);
|
|
WRITE("%S", Metadata::required_textual(pack, I"^name"));
|
|
IndexUtilities::link_package(OUT, pack);
|
|
HTML_TAG("br");
|
|
if (Str::len(description) > 0) {
|
|
WRITE("%S", description);
|
|
HTML_TAG("br");
|
|
}
|
|
Localisation::roman_ti(description, LD, I"Index.Elements.Fi.Resource",
|
|
Filenames::get_leafname(F), (int) id);
|
|
HTML::end_html_row(OUT);
|
|
|
|
@h Internal files.
|
|
|
|
@d EXTERNAL_TEXT_FILE_NFSMF 0
|
|
@d EXTERNAL_BINARY_FILE_NFSMF 1
|
|
@d INTERNAL_TEXT_FILE_NFSMF 2
|
|
@d INTERNAL_BINARY_FILE_NFSMF 3
|
|
|
|
@<Index the internal files@> =
|
|
HTML_OPEN("p");
|
|
Localisation::bold(OUT, LD, I"Index.Elements.Fi.ListOfInternalFiles");
|
|
HTML_CLOSE("p");
|
|
if (InterNodeList::array_len(inv->internal_file_nodes) == 0) {
|
|
HTML_OPEN("p");
|
|
Localisation::roman(OUT, LD, I"Index.Elements.Fi.NoInternalFiles");
|
|
HTML_CLOSE("p");
|
|
} else {
|
|
@<Tabulate the internal files@>;
|
|
}
|
|
|
|
@<Tabulate the internal files@> =
|
|
HTML::begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
|
|
inter_package *pack;
|
|
LOOP_OVER_INVENTORY_PACKAGES(pack, i, inv->internal_file_nodes) {
|
|
inter_ti id = Metadata::read_numeric(pack, I"^resource_id");
|
|
text_stream *filename_as_text = Metadata::required_textual(pack, I"^filename");
|
|
filename *F = Filenames::from_text(filename_as_text);
|
|
inter_ti format = Metadata::read_numeric(pack, I"^internal_file_format");
|
|
TEMPORARY_TEXT(description)
|
|
TEMPORARY_TEXT(preview)
|
|
@<Find internal file preview@>;
|
|
@<Render a table row for the internal file@>;
|
|
DISCARD_TEXT(description)
|
|
DISCARD_TEXT(preview)
|
|
}
|
|
HTML::end_html_table(OUT);
|
|
|
|
@<Find internal file preview@> =
|
|
FILE *INTERNAL_FILE = Filenames::fopen(F, "rb");
|
|
if (INTERNAL_FILE) {
|
|
switch (format) {
|
|
case INTERNAL_TEXT_FILE_NFSMF:
|
|
WRITE_TO(description, "%S", filename_as_text);
|
|
@<Offer a textual preview@>;
|
|
break;
|
|
case INTERNAL_BINARY_FILE_NFSMF:
|
|
WRITE_TO(description, "%S", filename_as_text);
|
|
@<Offer a binary preview@>;
|
|
break;
|
|
}
|
|
} else {
|
|
Localisation::italic(description, LD, I"Index.Elements.Fi.MissingInternalFile");
|
|
}
|
|
|
|
@<Offer a textual preview@> =
|
|
for (int row = 0; row < 6; ) {
|
|
int col = 0;
|
|
unsigned int B, line_ended = FALSE;
|
|
while (BinaryFiles::read_int8(INTERNAL_FILE, &B)) {
|
|
if ((B == 10) || (B == 13)) { line_ended = TRUE; break; }
|
|
if (col++ >= 80) { WRITE_TO(preview, "[...]"); line_ended = TRUE; break; }
|
|
if ((B >= 0x20) && (B <= 0x7E)) WRITE_TO(preview, "%c", B);
|
|
else WRITE_TO(preview, "?");
|
|
}
|
|
if (line_ended == FALSE) break;
|
|
if (col > 0) row++;
|
|
WRITE_TO(preview, "\n");
|
|
}
|
|
|
|
@<Offer a binary preview@> =
|
|
for (int row = 0; row < 6; row++) {
|
|
unsigned int bytes[16];
|
|
for (int col = 0; col < 16; col++) {
|
|
if (!BinaryFiles::read_int8(INTERNAL_FILE, &(bytes[col]))) {
|
|
for (; col < 16; col++) bytes[col] = 256;
|
|
row = 6; break;
|
|
}
|
|
}
|
|
for (int col = 0; col < 16; col++) {
|
|
if (bytes[col] < 256) WRITE_TO(preview, "%02x ", bytes[col]);
|
|
else WRITE_TO(preview, ".. ");
|
|
}
|
|
for (int col = 0; col < 16; col++) {
|
|
if ((bytes[col] >= 0x20) && (bytes[col] <= 0x7E)) WRITE_TO(preview, "%c", bytes[col]);
|
|
else WRITE_TO(preview, ".");
|
|
}
|
|
WRITE_TO(preview, "\n");
|
|
}
|
|
|
|
@<Render a table row for the internal file@> =
|
|
HTML::first_html_column(OUT, THUMBNAIL_WIDTH+10);
|
|
if (Str::len(description) == 0) {
|
|
HTML_TAG_WITH("img", "border=\"0\" src=\"inform:/doc_images/image_problem.png\"");
|
|
} else {
|
|
HTML_TAG_WITH("img", "border=\"0\" src=\"inform:/doc_images/data.png\"");
|
|
}
|
|
WRITE(" ");
|
|
HTML::next_html_column(OUT, 0);
|
|
HTML_OPEN_WITH("p", "class=\"hang\"");
|
|
switch (format) {
|
|
case INTERNAL_TEXT_FILE_NFSMF: WRITE("(text) "); break;
|
|
case INTERNAL_BINARY_FILE_NFSMF: WRITE("(binary) "); break;
|
|
}
|
|
WRITE("%S", Metadata::required_textual(pack, I"^name"));
|
|
IndexUtilities::link_package(OUT, pack);
|
|
if (Str::len(description) > 0) {
|
|
HTML_TAG("br");
|
|
WRITE("%S", description);
|
|
}
|
|
HTML_CLOSE("p");
|
|
if (Str::len(preview) > 0) {
|
|
HTML_OPEN("pre");
|
|
int N = Streams::get_indentation(OUT);
|
|
Streams::set_indentation(OUT, 0);
|
|
WRITE("\n%S", preview);
|
|
Streams::set_indentation(OUT, N);
|
|
HTML_CLOSE("pre");
|
|
WRITE("\n");
|
|
}
|
|
HTML_OPEN("p");
|
|
Localisation::roman_ti(description, LD, I"Index.Elements.Fi.Resource",
|
|
Filenames::get_leafname(F), (int) id);
|
|
HTML_CLOSE("p");
|
|
HTML::end_html_row(OUT);
|
|
|
|
@h Files.
|
|
This is more or less perfunctory, but still of some use, if only as a list.
|
|
|
|
@<Index the files@> =
|
|
HTML_OPEN("p");
|
|
Localisation::bold(OUT, LD, I"Index.Elements.Fi.ListOfFiles");
|
|
HTML_CLOSE("p");
|
|
if (InterNodeList::array_len(inv->file_nodes) == 0) {
|
|
HTML_OPEN("p");
|
|
Localisation::roman(OUT, LD, I"Index.Elements.Fi.NoFiles");
|
|
HTML_CLOSE("p");
|
|
} else {
|
|
@<Tabulate the files@>;
|
|
}
|
|
|
|
@<Tabulate the files@> =
|
|
HTML::begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
|
|
inter_package *pack;
|
|
LOOP_OVER_INVENTORY_PACKAGES(pack, i, inv->file_nodes) {
|
|
HTML::first_html_column(OUT, THUMBNAIL_WIDTH+10);
|
|
int is_binary = (int) Metadata::read_optional_numeric(pack, I"^is_binary");
|
|
if (is_binary) {
|
|
HTML_TAG_WITH("img", "border=\"0\" src=\"inform:/doc_images/exf_binary.png\"");
|
|
} else {
|
|
HTML_TAG_WITH("img", "border=\"0\" src=\"inform:/doc_images/exf_text.png\"");
|
|
}
|
|
WRITE(" ");
|
|
HTML::next_html_column(OUT, 0);
|
|
WRITE("%S", Metadata::required_textual(pack, I"^name"));
|
|
IndexUtilities::link_package(OUT, pack);
|
|
HTML_TAG("br");
|
|
if (is_binary)
|
|
Localisation::roman_t(OUT, LD, I"Index.Elements.Fi.BinaryFile",
|
|
Metadata::required_textual(pack, I"^leafname"));
|
|
else
|
|
Localisation::roman_t(OUT, LD, I"Index.Elements.Fi.TextFile",
|
|
Metadata::required_textual(pack, I"^leafname"));
|
|
WRITE(" - ");
|
|
if (Metadata::read_optional_numeric(pack, I"^file_owned")) {
|
|
Localisation::roman(OUT, LD, I"Index.Elements.Fi.FileOwnedByThis");
|
|
} else if (Metadata::read_optional_numeric(pack, I"^file_owned_by_other")) {
|
|
Localisation::roman(OUT, LD, I"Index.Elements.Fi.FileOwnedByOther");
|
|
} else {
|
|
Localisation::roman_t(OUT, LD, I"Index.Elements.Fi.FileOwnedBy",
|
|
Metadata::required_textual(pack, I"^file_owner"));
|
|
}
|
|
HTML::end_html_row(OUT);
|
|
}
|
|
HTML::end_html_table(OUT);
|