예제 #1
0
std::vector<uint32_t> TextTileSet::copy_glyph_bitmap(const ft::BitmapGlyph& glyph) const
{
    auto bitmap_size = tile_width() * tile_height();  
    std::vector<uint32_t> bitmap_data(bitmap_size);
    
    const auto source_data = glyph.buffer();
    if(source_data)
    {
        for(auto y = 0; y < glyph.rows(); ++y)
        {
            for(auto x = 0; x < glyph.width(); ++x)
            {
                auto x_pos = x + glyph.left();
                auto y_pos = y + tile_height() - glyph.top() - m_vert_shift;
                auto index = x_pos + y_pos * tile_width();

                if(index < bitmap_size && index >= 0)
                {
                    bitmap_data[index] = 0x00FFFFFF | (source_data[x + y * glyph.pitch()] << 24);
                }
            }
        }
    }
    return bitmap_data;
}
예제 #2
0
void TextTileSet::add_glyph(const TileLocation& location, unsigned int character)
{
    auto glyph = std::static_pointer_cast<const ft::BitmapGlyph>(
        m_font_face->get_glyph(character)); 

    auto bitmap_data = copy_glyph_bitmap(*glyph); 

    Rectanglei tile_location(location.bottom_left.x * texture_width(),
            location.bottom_left.y * texture_height(),
            tile_width(), tile_height());
    
    auto bound_texture = m_context->bind_texture_array_2d(*m_texture);
    bound_texture.update_data(tile_location, location.layer, 1,
            gl::Texture::DataPixelFormat::BGRA, 
            gl::Texture::PixelType::UByte, bitmap_data.data());
}
예제 #3
0
void TextTileSet::compute_geometries(int min_slots)
{
    auto g_character = std::static_pointer_cast<const ft::BitmapGlyph>(m_font_face->get_glyph('g'));
	int below_baseline = g_character->top() - g_character->rows();
	if(below_baseline > 0)
	{
		below_baseline = 0;
	}

    m_vert_shift = -below_baseline;
	m_tile_height = m_vert_shift + m_font_face->line_height();
    
    m_texture_layers = std::ceil(static_cast<float>(min_slots) /
           (tiles_per_line() * tile_lines()));

    m_cell_width = tile_width() / static_cast<double>(texture_width());
    m_cell_height = tile_height() / static_cast<double>(texture_height());

    auto tile_count = tiles_per_line() * tile_lines() * m_texture_layers;
    m_free_slots.resize(tile_count);
    m_tiles.resize(tile_count);
}
예제 #4
0
파일: djv_iff_save.cpp 프로젝트: UIKit0/djv
void Save::save(const Image & in, const Image_Io_Frame_Info & frame)
    throw (Error)
{
    //DJV_DEBUG("Save::save");
    //DJV_DEBUG_PRINT("in = " << in);

    // Open the file.

    _open(_file.get(frame.frame));

    // Convert the image.

    const Pixel_Data * p = &in;

    if (in.info() != _info)
    {
        //DJV_DEBUG_PRINT("convert = " << _image);

        _image.zero();

        Gl_Image::copy(in, _image);

        p = &_image;
    }

    // Write the file.

    const int w = p->w(), h = p->h();
    const int channels = Pixel::channels(p->info().pixel);
    const int channel_bytes = Pixel::channel_bytes(p->info().pixel);
    const int bytes = Pixel::bytes(p->info().pixel);

    bool compress = _options.compression ? true : false;

    uint32_t length = 0;

    //DJV_DEBUG_PRINT("channels = " << channels);
    //DJV_DEBUG_PRINT("channel_bytes = " << channel_bytes);
    //DJV_DEBUG_PRINT("bytes = " << bytes);

    size_t pos = 0;
    pos = _io.position();

    //DJV_DEBUG_PRINT("position = " << static_cast<int>(pos));

    // 'FOR4' type
    _io.set_u8('F');
    _io.set_u8('O');
    _io.set_u8('R');
    _io.set_u8('4');

    // 'FOR4' length
    // NOTE: only reserved for now.
    _io.set_u32(length);

    // 'TBMP' type
    _io.set_u8('T');
    _io.set_u8('B');
    _io.set_u8('M');
    _io.set_u8('P');

    // Write tiles.

    V2i size = tile_size (w, h);

    // Y order.

    for (int y = 0; y < size.y; y++)
    {
        // X order.

        for (int x = 0; x < size.x; x++)
        {
            // Set tile coordinates.
            uint16_t xmin, xmax, ymin, ymax;

            // Set xmin and xmax.
            xmin = x * tile_width();
            xmax = Math::min(xmin + tile_width(), w) - 1;

            // Set ymin and ymax.
            ymin = y * tile_height();
            ymax = Math::min(ymin + tile_height(), h) - 1;

            // Set width and height.
            uint32_t tw = xmax - xmin + 1;
            uint32_t th = ymax - ymin + 1;

            // Set type.
            _io.set_u8('R');
            _io.set_u8('G');
            _io.set_u8('B');
            _io.set_u8('A');

            // Length.
            uint32_t length = tw * th * bytes;

            // Tile length.
            uint32_t tile_length = length;

            // Align.
            length = align_size(length, 4);

            // Append xmin, xmax, ymin and ymax.
            length += 8;

            // Tile compression.
            bool tile_compress = compress;

            // Set bytes.
            Memory_Buffer<uint8_t> tile(tile_length);
            uint8_t * out_p = tile();

            // Handle 8-bit data.
            if (p->info().pixel == Pixel::RGB_U8 ||
                p->info().pixel == Pixel::RGBA_U8)
            {
                if (tile_compress)
                {
                    uint32_t index = 0, size = 0;

                    // Set bytes.
                    // NOTE: prevent buffer overrun.
                    Memory_Buffer<uint8_t> tmp(tile_length * 2);

                    // Map: RGB(A)8 RGBA to BGRA
                    for (int c = (channels * channel_bytes) - 1; c >= 0; --c)
                    {
                        Memory_Buffer<uint8_t> in(tw * th);
                        uint8_t * in_p = in();

                        // Data.

                        for (uint16_t py = ymin; py <= ymax; py++)
                        {
                            const uint8_t * in_dy = p->data(0, py);

                            for (uint16_t px = xmin; px <= xmax; px++)
                            {
                                // Get pixel.
                                uint8_t pixel;
                                const uint8_t * in_dx = in_dy + px * bytes + c;
                                Memory::copy(in_dx, &pixel, 1);
                                // Set pixel.
                                *in_p++ = pixel;
                            }
                        }

                        // Compress

                        size = rle_save(in(), tmp() + index, tw * th);
                        index += size;
                    }

                    // If size exceeds tile length use uncompressed.

                    if (index < tile_length)
                    {
                        Memory::copy(tmp(), tile(), index);

                        // Set tile length.
                        tile_length = index;

                        // Append xmin, xmax, ymin and ymax.
                        length = index + 8;

                        // Set length.
                        uint32_t align = align_size(length, 4);

                        if (align > length)
                        {
                            out_p = tile() + index;

                            // Pad.
                            for (int i = 0;
                                i < static_cast<int>(align - length);
                                i++)
                            {
                                *out_p++ = '\0';
                                tile_length++;
                            }
                        }
                    }
                    else
                    {
                        tile_compress = false;
                    }
                }

                if (!tile_compress)
                {
                    for (uint16_t py = ymin; py <= ymax; py++)
                    {
                        const uint8_t * in_dy = p->data(0, py);

                        for (uint16_t px = xmin; px <= xmax; px++)
                        {
                            // Map: RGB(A)8 RGBA to BGRA
                            for (int c = channels - 1; c >= 0; --c)
                            {
                                // Get pixel.
                                uint8_t pixel;
                                const uint8_t * in_dx =
                                    in_dy + px * bytes + c * channel_bytes;
                                Memory::copy(in_dx, &pixel, 1);
                                // Set pixel.
                                *out_p++ = pixel;
                            }
                        }
                    }
                }
            }
            // Handle 16-bit data.
            else if (
                p->info().pixel == Pixel::RGB_U16 ||
                p->info().pixel == Pixel::RGBA_U16)
            {
                if (tile_compress)
                {
                    uint32_t index = 0, size = 0;

                    // Set bytes.
                    // NOTE: prevent buffer overrun.
                    Memory_Buffer<uint8_t> tmp(tile_length * 2);

                    // Set map.
                    int* map = NULL;

                    if (Memory::endian () == Memory::LSB)
                    {
                        int rgb16[] = { 0, 2, 4, 1, 3, 5 };
                        int rgba16[] = { 0, 2, 4, 7, 1, 3, 5, 6 };

                        if (_info.pixel == Pixel::RGB_U16)
                        {
                            map = rgb16;
                        }
                        else
                        {
                            map = rgba16;
                        }
                    }
                    else
                    {
                        int rgb16[] = { 1, 3, 5, 0, 2, 4 };
                        int rgba16[] = { 1, 3, 5, 7, 0, 2, 4, 6 };

                        if (_info.pixel == Pixel::RGB_U16)
                        {
                            map = rgb16;
                        }
                        else
                        {
                            map = rgba16;
                        }
                    }

                    // Map: RGB(A)16 RGBA to BGRA
                    for (int c = (channels * channel_bytes) - 1; c >= 0; --c)
                    {
                        int mc = map[c];
                        Memory_Buffer<uint8_t> in(tw * th);
                        uint8_t * in_p = in();

                        // Data.

                        for (uint16_t py = ymin; py <= ymax; py++)
                        {
                            const uint8_t * in_dy = p->data(0, py);

                            for (uint16_t px = xmin; px <= xmax; px++)
                            {
                                // Get pixel.
                                uint8_t pixel;
                                const uint8_t * in_dx = in_dy + px * bytes + mc;
                                Memory::copy(in_dx, &pixel, 1);
                                // Set pixel.
                                *in_p++ = pixel;
                            }
                        }

                        // Compress

                        size = rle_save(in(), tmp() + index, tw * th);
                        index += size;
                    }

                    // If size exceeds tile length use uncompressed.

                    if (index < tile_length)
                    {
                        Memory::copy(tmp(), tile(), index);

                        // Set tile length.
                        tile_length = index;

                        // Append xmin, xmax, ymin and ymax.
                        length = index + 8;

                        // Set length.
                        uint32_t align = align_size(length, 4);

                        if (align > length)
                        {
                            out_p = tile() + index;

                            // Pad.
                            for (
                                int i = 0;
                                i < static_cast<int>(align - length);
                                i++)
                            {
                                *out_p++ = '\0';
                                tile_length++;
                            }
                        }
                    }
                    else
                    {
                        tile_compress = false;
                    }
                }

                if (!tile_compress)
                {
                    for (uint16_t py = ymin; py <= ymax; py++)
                    {
                        const uint8_t * in_dy = p->data(0, py);

                        for (uint16_t px = xmin; px <= xmax; px++)
                        {
                            // Map: RGB(A)16 RGBA to BGRA
                            for (int c = channels - 1; c >= 0; --c)
                            {
                                uint16_t pixel;
                                const uint8_t * in_dx =
                                    in_dy + px * bytes + c * channel_bytes;

                                if (Memory::endian () == Memory::LSB)
                                {
                                    Memory::endian(in_dx, &pixel, 1, 2);
                                }
                                else
                                {
                                    Memory::copy(in_dx, &pixel, 2);
                                }

                                // Set pixel.
                                *out_p++ = pixel;
                                out_p++;
                            }
                        }
                    }
                }
            }

            // Set length.
            _io.set_u32(length);

            // Set xmin, xmax, ymin and ymax.
            _io.set_u16(xmin);
            _io.set_u16(ymin);
            _io.set_u16(xmax);
            _io.set_u16(ymax);

            // Write.
            _io.set(tile(), tile_length);
        }
    }

    // Set FOR4 CIMG and FOR4 TBMP size
    uint32_t p0 = _io.position() - 8;
    uint32_t p1 = p0 - pos;

    // NOTE: FOR4 <size> CIMG
    _io.position (4);
    _io.set_u32 (p0);

    // NOTE: FOR4 <size> TBMP
    _io.position (pos + 4);
    _io.set_u32 (p1);
    _io.close();
}