Example #1
0
/** Extracts the glyph outlines of a given character.
 *  @param[in]  c character code of requested glyph
 *  @param[out] glyph path segments of the glyph outline
 *  @param[in]  cb optional callback object for tracer class
 *  @return true if outline could be computed */
bool PhysicalFont::getGlyph (int c, GraphicsPath<Int32> &glyph, GFGlyphTracer::Callback *cb) const {
	if (type() == MF) {
		const Glyph *cached_glyph=0;
		if (CACHE_PATH) {
			_cache.write(CACHE_PATH);
			_cache.read(name().c_str(), CACHE_PATH);
			cached_glyph = _cache.getGlyph(c);
		}
		if (cached_glyph) {
			glyph = *cached_glyph;
			return true;
		}
		else {
			string gfname;
			if (createGF(gfname)) {
				try {
					double ds = getMetrics() ? getMetrics()->getDesignSize() : 1;
					GFGlyphTracer tracer(gfname, unitsPerEm()/ds, cb);
					tracer.setGlyph(glyph);
					tracer.executeChar(c);
					glyph.closeOpenSubPaths();
					if (CACHE_PATH)
						_cache.setGlyph(c, glyph);
					return true;
				}
				catch (GFException &e) {
					// @@ print error message
				}
			}
			else {
				Message::wstream(true) << "failed creating " << name() << ".gf\n";
			}
		}
	}
	else { // vector fonts (OTF, PFB, TTF, TTC)
		bool ok=true;
		FontEngine::instance().setFont(*this);
		if (const FontMap::Entry *entry = fontMapEntry())
			if (Subfont *sf = entry->subfont)
				c = sf->decode(c);
		ok = FontEngine::instance().traceOutline(decodeChar(c), glyph, false);
		glyph.closeOpenSubPaths();
		return ok;
	}
	return false;
}
Example #2
0
TEST(GraphicsPathTest, closeOpenSubPaths) {
	GraphicsPath<double> path;
	path.moveto(0,0);
	path.lineto(1,0);
	path.lineto(1,1);
	path.lineto(0,1);
	path.moveto(10,10);
	path.lineto(11,10);
	path.lineto(11,11);
	path.lineto(10,11);
	path.closeOpenSubPaths();
	ostringstream oss;
	path.writeSVG(oss, false);
	EXPECT_EQ(oss.str(), "M0 0H1V1H0ZM10 10H11V11H10Z");
}