AtomicPtr LoaderDFF::readAtomic(FrameList &framelist, GeometryList &geometrylist, const RWBStream &stream) { auto atomicStream = stream.getInnerStream(); auto atomicStructID = atomicStream.getNextChunk(); if (atomicStructID != CHUNK_STRUCT) { throw DFFLoaderException("Atomic missing struct chunk"); } auto data = atomicStream.getCursor(); auto frame = *(std::uint32_t *)data; data += sizeof(std::uint32_t); auto geometry = *(std::uint32_t *)data; data += sizeof(std::uint32_t); auto flags = *(std::uint32_t *) data; // Verify the atomic's particulars RW_CHECK(frame < framelist.size(), "atomic frame " << frame << " out of bounds"); RW_CHECK(geometry < geometrylist.size(), "atomic geometry " << geometry << " out of bounds"); auto atomic = std::make_shared<Atomic>(); if (geometry < geometrylist.size()) { atomic->setGeometry(geometrylist[geometry]); } if (frame < framelist.size()) { atomic->setFrame(framelist[frame]); } atomic->setFlags(flags); return atomic; }
// Generates the geometry required to render a single line of text. int FontFaceHandle::GenerateString(GeometryList& geometry, const WString& string, const Vector2f& position, const Colourb& colour, int layer_configuration_index, word default_character) const { int geometry_index = 0; int line_width = 0; ROCKET_ASSERT(layer_configuration_index >= 0); ROCKET_ASSERT(layer_configuration_index < (int) layer_configurations.size()); // Fetch the requested configuration and generate the geometry for each one. const LayerConfiguration& layer_configuration = layer_configurations[layer_configuration_index]; for (size_t i = 0; i < layer_configuration.size(); ++i) { FontFaceLayer* layer = layer_configuration[i]; Colourb layer_colour; if (layer == base_layer) layer_colour = colour; else layer_colour = layer->GetColour(); // Resize the geometry list if required. if ((int) geometry.size() < geometry_index + layer->GetNumTextures()) geometry.resize(geometry_index + layer->GetNumTextures()); // Bind the textures to the geometries. for (int i = 0; i < layer->GetNumTextures(); ++i) geometry[geometry_index + i].SetTexture(layer->GetTexture(i)); line_width = 0; word prior_character = 0; const word* string_iterator = string.CString(); const word* string_end = string.CString() + string.Length(); word final_character; for (; string_iterator != string_end; string_iterator++) { final_character = *string_iterator; FontGlyphMap::const_iterator iterator = glyphs.find(*string_iterator); if (iterator == glyphs.end()) { if (default_character >= 32) { iterator = glyphs.find(default_character); if (iterator == glyphs.end()) { continue; } else { final_character = default_character; } } else { continue; } } // Adjust the cursor for the kerning between this character and the previous one. if (prior_character != 0) line_width += GetKerning(prior_character, final_character); layer->GenerateGeometry(&geometry[geometry_index], final_character, Vector2f(position.x + line_width, position.y), layer_colour); line_width += iterator->second.advance; prior_character = final_character; } geometry_index += layer->GetNumTextures(); } // Cull any excess geometry from a previous generation. geometry.resize(geometry_index); return line_width; }