Пример #1
0
		void glyphTraverse(const std::string& text, std::function<void(stbtt_packedchar*)> fn)
		{
			auto cp_str = utils::utf8_to_codepoint(text);

			std::vector<char32_t> glyphs_to_add;
			for(char32_t cp : cp_str) {
				auto it = packed_char_.find(UnicodeRange(cp));
				if(it == packed_char_.end()) {
					glyphs_to_add.emplace_back(cp);
				}
			}
			if(!glyphs_to_add.empty()) {
				addGlyphsToTexture(glyphs_to_add);
			}

			for(char32_t cp : cp_str) {
				auto it = packed_char_.find(UnicodeRange(cp));
				if(it == packed_char_.end()) {
					cp = 0xfffd;
					it = packed_char_.find(UnicodeRange(0xfffd));
					if(it == packed_char_.end()) {
						continue;
					}
				}
				
				stbtt_packedchar* b = it->second.data() + cp - it->first.first;
				fn(b);
			}
		}
Пример #2
0
TEST(UnicodeRangeSet, Overlap) {
  Vector<UnicodeRange> ranges;
  ranges.append(UnicodeRange('0', '2'));
  ranges.append(UnicodeRange('1', '1'));
  ranges.append(UnicodeRange('3', '5'));
  ranges.append(UnicodeRange('4', '6'));
  RefPtr<UnicodeRangeSet> set = adoptRef(new UnicodeRangeSet(ranges));
  ASSERT_EQ(1u, set->size());
  EXPECT_EQ('0', set->rangeAt(0).from());
  EXPECT_EQ('6', set->rangeAt(0).to());
}
Пример #3
0
		void addGlyphsToTexture(const std::vector<char32_t>& codepoints) override
		{
			if(codepoints.empty()) {
				LOG_WARN("stb_impl::addGlyphsToTexture: no codepoints.");
				return;
			}
			int old_size = packed_char_.size();
			auto ttf_buffer = reinterpret_cast<const unsigned char*>(font_data_.c_str());
			if(font_size_ < 20.0f) {
				stbtt_PackSetOversampling(&pc_, 2, 2);
			}
			
			std::vector<stbtt_pack_range> ranges;
			char32_t last_cp = codepoints.front();
			char32_t first_cp = codepoints.front();
			int num_chars = 1;
			for(auto it = codepoints.begin() + 1; it != codepoints.end(); ++it) {
				char32_t cp = *it;
				if(cp == last_cp+1) {
					++num_chars;
				} else {
					auto& packed_data = packed_char_[UnicodeRange(first_cp, first_cp+num_chars-1)];
					packed_data.resize(num_chars);

					stbtt_pack_range range;
					range.num_chars_in_range          = num_chars;
					range.chardata_for_range          = packed_data.data();
					range.font_size                   = font_size_;
					range.first_unicode_char_in_range = first_cp;
					ranges.emplace_back(range);

					num_chars = 1;
					first_cp = cp;					
				}
				last_cp = cp;
			}
			auto& packed_data = packed_char_[UnicodeRange(first_cp, first_cp+num_chars-1)];
			packed_data.resize(num_chars);

			stbtt_pack_range range;
			range.num_chars_in_range          = num_chars;
			range.chardata_for_range          = packed_data.data();
			range.font_size                   = font_size_;
			range.first_unicode_char_in_range = first_cp;
			ranges.emplace_back(range);

			stbtt_PackFontRanges(&pc_, ttf_buffer, 0, ranges.data(), ranges.size());

			font_texture_->update2D(0, 0, 0, surface_width, surface_height, surface_width, pixels_.data());
		}
Пример #4
0
TEST(UnicodeRangeSet, Non8Bit) {
  Vector<UnicodeRange> ranges;
  ranges.append(UnicodeRange(0x3042, 0x3042));
  RefPtr<UnicodeRangeSet> set = adoptRef(new UnicodeRangeSet(ranges));
  ASSERT_EQ(1u, set->size());
  EXPECT_EQ(0x3042, set->rangeAt(0).from());
  EXPECT_EQ(0x3042, set->rangeAt(0).to());
  EXPECT_FALSE(set->intersectsWith(String("a")));
  EXPECT_TRUE(set->intersectsWith(String(hiraganaA)));
}
Пример #5
0
TEST(UnicodeRangeSet, TwoRanges) {
  Vector<UnicodeRange> ranges;
  ranges.append(UnicodeRange('6', '7'));
  ranges.append(UnicodeRange('2', '4'));
  RefPtr<UnicodeRangeSet> set = adoptRef(new UnicodeRangeSet(ranges));
  EXPECT_FALSE(set->isEntireRange());
  EXPECT_FALSE(set->intersectsWith(String()));
  EXPECT_FALSE(set->intersectsWith(String("1")));
  EXPECT_TRUE(set->intersectsWith(String("2")));
  EXPECT_TRUE(set->intersectsWith(String("3")));
  EXPECT_TRUE(set->intersectsWith(String("4")));
  EXPECT_FALSE(set->intersectsWith(String("5")));
  EXPECT_TRUE(set->intersectsWith(String("6")));
  EXPECT_TRUE(set->intersectsWith(String("7")));
  EXPECT_FALSE(set->intersectsWith(String("8")));
  ASSERT_EQ(2u, set->size());
  EXPECT_EQ('2', set->rangeAt(0).from());
  EXPECT_EQ('4', set->rangeAt(0).to());
  EXPECT_EQ('6', set->rangeAt(1).from());
  EXPECT_EQ('7', set->rangeAt(1).to());
}
Пример #6
0
QString MainWindow::refineString2(QString s)
{
    QString result = "";
    for (int i = 0; i < s.length(); ++i)
    {
        if (UnicodeRange(s.at(i)) != NON_JAPANESE)
        {
            result.append(s.at(i));
        }
    }
    return result;
}
Пример #7
0
		const std::vector<point>& getGlyphPath(const std::string& text) override
		{
			auto it = glyph_path_cache_.find(text);
			if(it != glyph_path_cache_.end()) {
				return it->second;
			}
			std::vector<point>& path = glyph_path_cache_[text];

			auto cp_str = utils::utf8_to_codepoint(text);

			std::vector<char32_t> glyphs_to_add;
			for(char32_t cp : cp_str) {
				auto it = packed_char_.find(UnicodeRange(cp));
				if(it == packed_char_.end()) {
					glyphs_to_add.emplace_back(cp);
				}
			}
			if(!glyphs_to_add.empty()) {
				addGlyphsToTexture(glyphs_to_add);
			}

			point pen;
			for(char32_t cp : cp_str) {
				path.emplace_back(pen);
				auto it = packed_char_.find(UnicodeRange(cp));
				if(it == packed_char_.end()) {
					cp = 0xfffd;
					it = packed_char_.find(UnicodeRange(0xfffd));
					if(it == packed_char_.end()) {
						continue;
					}
				}
				
				stbtt_packedchar *b = it->second.data() + cp - it->first.first;
				pen.x += static_cast<int>(b->xadvance * 65536.0f);
			}
			path.emplace_back(pen);

			return path;
		}
Пример #8
0
static CSSFontFace* createCSSFontFace(FontFace* fontFace, CSSValue* unicodeRange)
{
    Vector<UnicodeRange> ranges;
    if (CSSValueList* rangeList = toCSSValueList(unicodeRange)) {
        unsigned numRanges = rangeList->length();
        for (unsigned i = 0; i < numRanges; i++) {
            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->item(i));
            ranges.append(UnicodeRange(range->from(), range->to()));
        }
    }

    return new CSSFontFace(fontFace, ranges);
}
Пример #9
0
TEST(UnicodeRangeSet, SingleCharacter) {
  Vector<UnicodeRange> ranges;
  ranges.append(UnicodeRange('b', 'b'));
  RefPtr<UnicodeRangeSet> set = adoptRef(new UnicodeRangeSet(ranges));
  EXPECT_FALSE(set->isEntireRange());
  EXPECT_FALSE(set->intersectsWith(String()));
  EXPECT_FALSE(set->intersectsWith(String("a")));
  EXPECT_TRUE(set->intersectsWith(String("b")));
  EXPECT_FALSE(set->intersectsWith(String("c")));
  EXPECT_TRUE(set->intersectsWith(String("abc")));
  EXPECT_FALSE(set->intersectsWith(String(hiraganaA)));
  ASSERT_EQ(1u, set->size());
  EXPECT_EQ('b', set->rangeAt(0).from());
  EXPECT_EQ('b', set->rangeAt(0).to());
}
Пример #10
0
CSSFontFace::UnicodeRangeSet::UnicodeRangeSet(const Vector<UnicodeRange>& ranges)
    : m_ranges(ranges)
{
    if (m_ranges.isEmpty())
        return;

    std::sort(m_ranges.begin(), m_ranges.end());

    // Unify overlapping ranges.
    UChar32 from = m_ranges[0].from();
    UChar32 to = m_ranges[0].to();
    size_t targetIndex = 0;
    for (size_t i = 1; i < m_ranges.size(); i++) {
        if (to + 1 >= m_ranges[i].from()) {
            to = std::max(to, m_ranges[i].to());
        } else {
            m_ranges[targetIndex++] = UnicodeRange(from, to);
            from = m_ranges[i].from();
            to = m_ranges[i].to();
        }
    }
    m_ranges[targetIndex++] = UnicodeRange(from, to);
    m_ranges.shrink(targetIndex);
}
Пример #11
0
		long calculateCharAdvance(char32_t cp) override
		{
			//int advance = 0;
			//int bearing = 0;
			//stbtt_GetCodepointHMetrics(&font_handle_, cp, &advance, &bearing);
			//return static_cast<int>(advance * scale_ * 65536.0f);
			auto it = packed_char_.find(UnicodeRange(cp));
			if(it == packed_char_.end()) {
				int advance = 0;
				int bearing = 0;
				stbtt_GetCodepointHMetrics(&font_handle_, cp, &advance, &bearing);
				return static_cast<int>(advance * scale_ * 65536.0f);
			}		
			stbtt_packedchar *b = it->second.data() + cp - it->first.first;
			return static_cast<int>(b->xadvance * 65536.0f);
		}
Пример #12
0
// Joins this range with another that it is contiguous with.
UnicodeRange UnicodeRange::Join(const UnicodeRange& rhs)
{
	return UnicodeRange(Math::Min(min_codepoint, rhs.min_codepoint),
						   Math::Max(max_codepoint, rhs.max_codepoint));
}
Пример #13
0
		ColoredFontRenderablePtr createColoredRenderableFromPath(ColoredFontRenderablePtr font_renderable, const std::string& text, const std::vector<point>& path, const std::vector<KRE::Color>& colors) override
		{
			auto cp_string = utils::utf8_to_codepoint(text);
			int glyphs_in_text = 0;
			std::vector<char32_t> glyphs_to_add;
			for(char32_t cp : cp_string) {
				++glyphs_in_text;

				auto it = packed_char_.find(UnicodeRange(cp));
				if(it == packed_char_.end()) {
					glyphs_to_add.emplace_back(cp);
				}
			}
			if(!glyphs_to_add.empty()) {
				addGlyphsToTexture(glyphs_to_add);
			}
			ASSERT_LOG(glyphs_in_text == colors.size(), "Not enough/Too many colors for the text.");
			
			if(font_renderable == nullptr) {
				font_renderable = std::make_shared<ColoredFontRenderable>();
				font_renderable->setTexture(font_texture_);
			}

			int width = font_renderable->getWidth();
			int height = font_renderable->getHeight();
			int max_height = 0;

			std::vector<font_coord> coords;
			coords.reserve(glyphs_in_text * 6);
			int n = 0;
			for(char32_t cp : cp_string) {
				ASSERT_LOG(n < static_cast<int>(path.size()), "Insufficient points were supplied to create a path from the string '" << text << "'");
				auto& pt =path[n];
				auto it = packed_char_.find(UnicodeRange(cp));
				if(it == packed_char_.end()) {
					it = packed_char_.find(UnicodeRange(0xfffd));
					if(it == packed_char_.end()) {
						continue;
					}
				}

				stbtt_packedchar *b = it->second.data() + cp - it->first.first;

				//width += pt.x >> 16;
				//width += static_cast<int>(b->xoff2 - b->xoff);
				max_height = std::max(max_height, static_cast<int>(b->yoff2 - b->yoff));

				const float u1 = font_texture_->getTextureCoordW(0, b->x0);
				const float v1 = font_texture_->getTextureCoordH(0, b->y0);
				const float u2 = font_texture_->getTextureCoordW(0, b->x1);
				const float v2 = font_texture_->getTextureCoordH(0, b->y1);

				const float x1 = static_cast<float>(pt.x) / 65536.0f + b->xoff;
				const float y1 = static_cast<float>(pt.y) / 65536.0f + b->yoff;
				const float x2 = x1 + b->xoff2 - b->xoff;
				const float y2 = static_cast<float>(pt.y) / 65536.0f + b->yoff2;
				coords.emplace_back(glm::vec2(x1, y2), glm::vec2(u1, v2));
				coords.emplace_back(glm::vec2(x1, y1), glm::vec2(u1, v1));
				coords.emplace_back(glm::vec2(x2, y1), glm::vec2(u2, v1));

				coords.emplace_back(glm::vec2(x2, y1), glm::vec2(u2, v1));
				coords.emplace_back(glm::vec2(x1, y2), glm::vec2(u1, v2));
				coords.emplace_back(glm::vec2(x2, y2), glm::vec2(u2, v2));
				++n;
			}
			height += max_height;
			width = std::max(width, path.back().x >> 16);

			font_renderable->setWidth(width);
			font_renderable->setHeight(height);
			font_renderable->update(&coords);
			font_renderable->setVerticesPerColor(6);
			font_renderable->updateColors(colors);
			return font_renderable;
		}