/** 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; }
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"); }