void operator()(const std::u32string& str) {
     m_serializer->acquire(sizeof(std::uint32_t) + str.size());
     write_int(m_serializer, static_cast<std::uint32_t>(str.size()));
     for (char32_t c : str) {
         // force writer to use exactly 32 bit
         write_int(m_serializer, static_cast<std::uint32_t>(c));
     }
 }
void FreeTypeFont::doFillGlyphCache(GlyphCache& cache, const std::u32string& characters) {
    /** @bug Crash when atlas is too small */

    /* Get glyph codes from characters */
    std::vector<FT_UInt> charIndices;
    charIndices.resize(characters.size()+1);
    charIndices[0] = 0;
    std::transform(characters.begin(), characters.end(), charIndices.begin()+1,
        [this](const char32_t c) { return FT_Get_Char_Index(ftFont, c); });

    /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */
    std::sort(charIndices.begin(), charIndices.end());
    charIndices.erase(std::unique(charIndices.begin(), charIndices.end()), charIndices.end());

    /* Sizes of all characters */
    std::vector<Vector2i> charSizes;
    charSizes.reserve(charIndices.size());
    for(FT_UInt c: charIndices) {
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, c, FT_LOAD_DEFAULT) == 0);
        charSizes.push_back(Vector2i(ftFont->glyph->metrics.width, ftFont->glyph->metrics.height)/64);
    }

    /* Create texture atlas */
    const std::vector<Range2Di> charPositions = cache.reserve(charSizes);

    /* Render all characters to the atlas and create character map */
    Containers::Array<char> pixmap{Containers::ValueInit, std::size_t(cache.textureSize().product())};
    for(std::size_t i = 0; i != charPositions.size(); ++i) {
        /* Load and render glyph */
        /** @todo B&W only if radius != 0 */
        FT_GlyphSlot glyph = ftFont->glyph;
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0);
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0);

        /* Copy rendered bitmap to texture image */
        const FT_Bitmap& bitmap = glyph->bitmap;
        CORRADE_INTERNAL_ASSERT(std::abs(Int(bitmap.width)-charPositions[i].sizeX()) <= 2);
        CORRADE_INTERNAL_ASSERT(std::abs(Int(bitmap.rows)-charPositions[i].sizeY()) <= 2);
        for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout)
            for(Int xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout)
                pixmap[yout*cache.textureSize().x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin];

        /* Insert glyph parameters into cache */
        cache.insert(charIndices[i],
            Vector2i(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].sizeY()),
            charPositions[i]);
    }

    /* Set cache image */
    #ifndef MAGNUM_TARGET_GLES2
    Image2D image(PixelFormat::Red, PixelType::UnsignedByte, cache.textureSize(), std::move(pixmap));
    #else
    Image2D image(Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ?
        PixelFormat::Red : PixelFormat::Luminance, PixelType::UnsignedByte, cache.textureSize(), std::move(pixmap));
    #endif
    cache.setImage({}, image);
}
Exemple #3
0
bool iterator::split( const std::u32string &s )
{
	size_t n = s.size();
	if ( _value.compare( 0, n, s ) == 0 )
	{
		_next.insert( 0, _value.substr( n ) );
		_value.resize( n );
		return true;
	}

	return false;
}
int string::compare(const std::u32string & s) const noexcept
{
    size_type sz = size();
    size_type len = s.size();
    size_type n = std::min(sz, len);
    
    auto pos = cbegin();
    auto spos = s.cbegin();
    for ( ; n; pos++, spos++ )
    {
        if ( traits_type::lt(*pos, *spos) )
            return -1;
        if ( traits_type::lt(*spos, *pos) )
            return 1;
    }
    
    if ( sz < len )
        return -1;
    if ( sz > len )
        return 1;
    return 0;
}
//Вспомогательная функция подсчета объема "текста" в элементах-непосредственных потомках
size_t textSize(GumboNode *a)
{
	assert(a != nullptr && a->type == GUMBO_NODE_ELEMENT);
	size_t l_size = 0;
	for (size_t i = 0; i < a->v.element.children.length; i++)
	{
		GumboNode *const l_child = static_cast<GumboNode *>(a->v.element.children.data[i]);
		if (l_child->type != GUMBO_NODE_ELEMENT)
			continue;
		if (l_child->v.element.tag == GUMBO_TAG_SCRIPT ||
			l_child->v.element.tag == GUMBO_TAG_STYLE || l_child->v.element.tag == GUMBO_TAG_TEXTAREA)
			continue;
		for (size_t j = 0; j < l_child->v.element.children.length; j++)
		{
			GumboNode *const l_one = static_cast<GumboNode *>(l_child->v.element.children.data[j]);
			if (l_one->type != GUMBO_NODE_TEXT)
				continue;
			const std::u32string l_utf32text(Encoding::utf8to32(l_one->v.text.text));
			l_size += l_utf32text.size();
		}
	}
	return l_size;
}
bool isValidEmoji(std::u32string string) {
    if (string.size() == 1) {
        return !isRegionalIndicator(string.front());
    }
    return string.back() != 0x200D;
}
Exemple #7
0
std::string to_utf8(const std::u32string &s)
{
	std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> convert;
	auto p = reinterpret_cast<const int32_t *>(s.data());
	return convert.to_bytes(p, p + s.size());
}
int string::compare(size_type pos1, size_type n1, const std::u32string& str,
                    size_type pos2, size_type n2) const
{
    if ( n1 == 0 && n2 > 0 )
        return -1;
    
    size_type sz = (n1 == npos ? size() - pos1 : n1);
    size_type len = (n2 == npos ? str.size() - pos2 : n2);
    size_type n = std::min(sz, len);
    
    auto pos = cbegin()+pos1;
    auto spos = str.cbegin();
    for ( ; n; pos++, spos++ )
    {
        if ( traits_type::lt(*pos, *spos) )
            return -1;
        if ( traits_type::lt(*spos, *pos) )
            return 1;
    }
    
    if ( sz < len )
        return -1;
    if ( sz > len )
        return 1;
    return 0;
}